summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-01-14 16:29:20 +0100
committerKonstantin Käfer <mail@kkaefer.com>2014-01-14 16:29:20 +0100
commit60a8fdca5727bc57bd6526e5447e2cc41db1ada8 (patch)
treeb73da9de7e55b1f5257822885c68a14ff9fee9bc
parent654972bb3feb1f451a820afbc7c46e7e502ce687 (diff)
downloadqtlocation-mapboxgl-60a8fdca5727bc57bd6526e5447e2cc41db1ada8.tar.gz
fix runtime errors
-rw-r--r--include/llmr/geometry/linevertexbuffer.hpp1
-rw-r--r--include/llmr/map/map.hpp6
-rw-r--r--include/llmr/map/tile.hpp11
-rw-r--r--include/llmr/platform/platform.hpp4
-rw-r--r--include/llmr/renderer/painter.hpp4
-rw-r--r--include/llmr/util/vec2.hpp18
-rw-r--r--macosx/main.mm35
-rw-r--r--src/geometry/linevertexbuffer.cpp8
-rw-r--r--src/map/map.cpp34
-rw-r--r--src/map/pbf.hpp57
-rw-r--r--src/map/tile.cpp80
-rw-r--r--src/map/transform.cpp2
-rw-r--r--src/renderer/painter.cpp4
13 files changed, 170 insertions, 94 deletions
diff --git a/include/llmr/geometry/linevertexbuffer.hpp b/include/llmr/geometry/linevertexbuffer.hpp
index 4d23de9154..0583297f7b 100644
--- a/include/llmr/geometry/linevertexbuffer.hpp
+++ b/include/llmr/geometry/linevertexbuffer.hpp
@@ -8,6 +8,7 @@ namespace llmr {
class linevertexbuffer {
public:
linevertexbuffer();
+ ~linevertexbuffer();
void addDegenerate();
void addCoordinate(int16_t x, int16_t y);
diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp
index 745ccce89d..71387c0934 100644
--- a/include/llmr/map/map.hpp
+++ b/include/llmr/map/map.hpp
@@ -22,8 +22,8 @@ public:
void moveBy(double dx, double dy);
void scaleBy(double ds, double cx, double cy);
void rotateBy(double cx, double cy, double sx, double sy, double ex, double ey);
- void tileLoaded(tile *tile);
- void tileFailed(tile *tile);
+ void tileLoaded(std::shared_ptr<tile> tile);
+ void tileFailed(std::shared_ptr<tile> tile);
private:
void updateTiles();
@@ -35,7 +35,7 @@ private:
// int32_t min_zoom;
// int32_t max_zoom;
- std::vector<tile *> tiles;
+ std::vector<std::shared_ptr<tile>> tiles;
};
}
diff --git a/include/llmr/map/tile.hpp b/include/llmr/map/tile.hpp
index 95d0593f72..063e6a90bd 100644
--- a/include/llmr/map/tile.hpp
+++ b/include/llmr/map/tile.hpp
@@ -5,13 +5,18 @@
#include <stdint.h>
#include <vector>
+#include <mutex>
#include <llmr/util/vec2.hpp>
namespace llmr {
class tile {
public:
+ typedef std::shared_ptr<tile> ptr;
+
+public:
tile(int32_t z, int32_t x, int32_t y);
+ ~tile();
void setData(uint8_t *data, uint32_t bytes);
bool parse();
@@ -21,8 +26,8 @@ public:
void cancel();
- static uint64_t toID(int32_t z, int32_t x, int32_t y, int32_t w = 0);
- static vec4<int32_t> fromID(uint64_t id);
+ // static int64_t toID(int32_t z, int32_t x, int32_t y, int32_t w = 0);
+ // static vec4<int32_t> fromID(int64_t id);
public:
const int32_t z, x, y;
@@ -31,6 +36,8 @@ public:
linevertexbuffer lineVertex;
private:
+ std::mutex mutex;
+
// Source data
uint8_t *data;
uint32_t bytes;
diff --git a/include/llmr/platform/platform.hpp b/include/llmr/platform/platform.hpp
index 69efb68064..e198f5331c 100644
--- a/include/llmr/platform/platform.hpp
+++ b/include/llmr/platform/platform.hpp
@@ -1,6 +1,8 @@
#ifndef LLMR_PLATFORM_IOS
#define LLMR_PLATFORM_IOS
+#include <memory>
+
namespace llmr {
class tile;
@@ -8,7 +10,7 @@ class tile;
namespace platform {
void restart(void *obj);
-void request(void *obj, tile *tile);
+void request(void *obj, std::shared_ptr<tile> tile);
}
diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp
index e01f6828a1..83a9171aba 100644
--- a/include/llmr/renderer/painter.hpp
+++ b/include/llmr/renderer/painter.hpp
@@ -19,13 +19,13 @@ public:
void clear();
- void render(tile *tile);
+ void render(std::shared_ptr<tile> tile);
void switchShader(Shader *shader, float matrix[16]);
private:
void setupShaders();
- void changeMatrix(tile *tile);
+ void changeMatrix(std::shared_ptr<tile> tile);
public:
diff --git a/include/llmr/util/vec2.hpp b/include/llmr/util/vec2.hpp
index abc49e54bd..332f54f5f9 100644
--- a/include/llmr/util/vec2.hpp
+++ b/include/llmr/util/vec2.hpp
@@ -7,27 +7,27 @@ template <typename T = double>
struct vec2 {
T x, y;
- // inline bool operator==(const vec2& rhs) const {
- // return x == rhs.x && y == rhs.y;
- // }
+ inline bool operator==(const vec2& rhs) const {
+ return x == rhs.x && y == rhs.y;
+ }
};
template <typename T = double>
struct vec3 {
T x, y, z;
- // inline bool operator==(const vec3& rhs) const {
- // return x == rhs.x && y == rhs.y && z == rhs.z;
- // }
+ inline bool operator==(const vec3& rhs) const {
+ return x == rhs.x && y == rhs.y && z == rhs.z;
+ }
};
template <typename T = double>
struct vec4 {
T x, y, z, w;
- // inline bool operator==(const vec4& rhs) const {
- // return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
- // }
+ inline bool operator==(const vec4& rhs) const {
+ return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
+ }
};
diff --git a/macosx/main.mm b/macosx/main.mm
index 20b6cc174a..23d75b4679 100644
--- a/macosx/main.mm
+++ b/macosx/main.mm
@@ -162,7 +162,7 @@ public:
llmr::map *map;
};
-
+NSOperationQueue *queue = NULL;
MapView *view;
namespace llmr {
@@ -172,23 +172,26 @@ void restart(void *) {
view->dirty = true;
}
-void request(void *, tile *tile) {
- fprintf(stderr, "request %d/%d/%d\n", tile->z, tile->x, tile->y);
+void request(void *, tile::ptr tile) {
+ // fprintf(stderr, "request %d/%d/%d\n", tile->z, tile->x, tile->y);
- fprintf(stderr, "requesting tile\n");
+ // fprintf(stderr, "requesting tile\n");
// NSString *urlTemplate = @"http://api.tiles.mapbox.com/v3/mapbox.mapbox-streets-v4/%d/%d/%d.vector.pbf";
- NSString *urlTemplate = @"http://localhost:3333/gl/tiles/%d-%d-%d.vector.pbf";
+ NSString *urlTemplate = @"http://localhost:3333/gl/tiles/plain/%d-%d-%d.vector.pbf";
NSString *urlString = [NSString
stringWithFormat:urlTemplate,
tile->z,
tile->x,
tile->y];
NSURL *url = [NSURL URLWithString:urlString];
- NSLog(@"Requesting %@", urlString);
+ // NSLog(@"Requesting %@", urlString);
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
- NSOperationQueue *queue = [[NSOperationQueue alloc] init];
+ if (!queue) {
+ queue = [[NSOperationQueue alloc] init];
+ }
+
[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:queue
@@ -196,12 +199,22 @@ void request(void *, tile *tile) {
NSData * data,
NSError * error) {
if (error == nil) {
- tile->setData((uint8_t *)[data bytes], [data length]);
- if (tile->parse()) {
+ NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
+ int code = [httpResponse statusCode];
+
+ if (code == 200) {
+ tile->setData((uint8_t *)[data bytes], [data length]);
+ if (tile->parse()) {
+ dispatch_async(dispatch_get_main_queue(), ^ {
+ view->map->tileLoaded(tile);
+ });
+ return;
+ }
+ } else {
+ fprintf(stderr, "[%s] status code %d\n", [urlString UTF8String], code);
dispatch_async(dispatch_get_main_queue(), ^ {
- view->map->tileLoaded(tile);
+ view->map->tileFailed(tile);
});
- return;
}
}
diff --git a/src/geometry/linevertexbuffer.cpp b/src/geometry/linevertexbuffer.cpp
index 04fd1c6c23..2086a0e865 100644
--- a/src/geometry/linevertexbuffer.cpp
+++ b/src/geometry/linevertexbuffer.cpp
@@ -9,6 +9,12 @@ linevertexbuffer::linevertexbuffer()
: buffer(0) {
}
+linevertexbuffer::~linevertexbuffer() {
+ if (buffer != 0) {
+ glDeleteBuffers(1, &buffer);
+ }
+}
+
void linevertexbuffer::addDegenerate() {
array.push_back(32767);
array.push_back(0);
@@ -27,7 +33,7 @@ uint32_t linevertexbuffer::length() {
void linevertexbuffer::bind() {
if (buffer == 0) {
glGenBuffers(1, &buffer);
- fprintf(stderr, "new buffer id: %d\n", buffer);
+ // fprintf(stderr, "new buffer id: %d\n", buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, array.size() * sizeof(uint16_t), array.data(), GL_STATIC_DRAW);
} else {
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 1fcf5d6636..f488899939 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -65,11 +65,14 @@ void map::updateTiles() {
br.x = fmin(max_dim, ceil(fmax(box.tr.x, box.br.x)));
br.y = fmin(max_dim, ceil(fmax(box.bl.y, box.br.y)));
+ typedef vec3<int32_t> tile_id;
+
// TODO: Discard tiles that are outside the viewport
- std::vector<uint64_t> required;
+ std::vector<tile_id> required;
for (int32_t y = tl.y; y < br.y; y++) {
for (int32_t x = tl.x; x < br.x; x++) {
- required.push_back(tile::toID(zoom, x, y));
+ tile_id id; id.z = zoom; id.x = x; id.y = y;
+ required.push_back(id);
}
}
@@ -79,17 +82,17 @@ void map::updateTiles() {
// Remove tiles that we definitely don't need, i.e. tiles that are not on
// the required list.
- for (std::vector<tile *>::iterator it = tiles.begin(); it != tiles.end(); it++) {
- tile *tile = *it;
- uint64_t id = tile::toID(tile->z, tile->x, tile->y);
- std::vector<uint64_t>::const_iterator required_it = std::find(required.begin(), required.end(), id);
+ for (std::vector<tile::ptr>::iterator it = tiles.begin(); it != tiles.end(); it++) {
+ tile::ptr& tile = *it;
+ tile_id id; id.z = tile->z; id.x = tile->x; id.y = tile->y;
+ std::vector<tile_id>::const_iterator required_it = std::find(required.begin(), required.end(), id);
bool retain = required_it != required.end();
if (retain) {
// We already have the tile; remove it from the list of required tiles.
required.erase(required_it);
} else {
// We don't need this tile, so we can remove it entirely.
- std::vector<class tile *>::iterator to_remove = it - 1;
+ std::vector<tile::ptr>::iterator to_remove = it - 1;
tile->cancel();
tiles.erase(it);
it = to_remove;
@@ -98,9 +101,8 @@ void map::updateTiles() {
// Required now only contains those tiles that are not yet in the list of
// tiles, so we should add them all.
- for (int64_t id : required) {
- vec4<int32_t> tile_coord = tile::fromID(id);
- tile *tile = new class tile(tile_coord.z, tile_coord.x, tile_coord.y);
+ for (tile_id& id : required) {
+ tile::ptr tile = std::make_shared<class tile>(id.z, id.x, id.y);
tiles.push_back(tile);
platform::request(this, tile);
}
@@ -109,7 +111,7 @@ void map::updateTiles() {
bool map::render() {
painter->clear();
- for (tile *tile : tiles) {
+ for (tile::ptr& tile : tiles) {
// painter->viewport();
if (tile->loaded) {
painter->render(tile);
@@ -119,12 +121,12 @@ bool map::render() {
return false;
}
-void map::tileLoaded(tile *tile) {
+void map::tileLoaded(tile::ptr tile) {
platform::restart(this);
}
-void map::tileFailed(tile *tile) {
- fprintf(stderr, "[%8zx] tile failed to load %d/%d/%d\n",
- std::hash<std::thread::id>()(std::this_thread::get_id()),
- tile->z, tile->x, tile->y);
+void map::tileFailed(tile::ptr tile) {
+ // fprintf(stderr, "[%8zx] tile failed to load %d/%d/%d\n",
+ // std::hash<std::thread::id>()(std::this_thread::get_id()),
+ // tile->z, tile->x, tile->y);
}
diff --git a/src/map/pbf.hpp b/src/map/pbf.hpp
index b9ed95a1a0..41192d7b74 100644
--- a/src/map/pbf.hpp
+++ b/src/map/pbf.hpp
@@ -13,6 +13,12 @@
#include <string>
// #include <cassert>
+#define PBF_USE_SETJMP
+
+#ifdef PBF_USE_SETJMP
+#include <csetjmp>
+#endif
+
namespace llmr {
struct pbf {
@@ -29,9 +35,6 @@ struct pbf {
// inline int64_t int64();
inline bool boolean();
- template <typename T, typename... Args>
- inline T *message(const Args&... args);
-
inline void skip();
inline void skipValue(uint32_t val);
inline void skipBytes(uint32_t bytes);
@@ -40,6 +43,17 @@ struct pbf {
const uint8_t *end;
uint32_t value;
uint32_t tag;
+
+ enum error_code {
+ UNTERMINATED_VARINT = 1,
+ UNKNOWN_TYPE = 2,
+ END_OF_BUFFER = 3
+ };
+
+ #ifdef PBF_USE_SETJMP
+ std::jmp_buf jump_buffer;
+ std::string msg;
+ #endif
};
pbf::pbf(const unsigned char *data, uint32_t length)
@@ -76,7 +90,10 @@ T pbf::varint()
int bitpos;
for (bitpos = 0; bitpos < 70 && (byte & 0x80); bitpos += 7) {
if (data >= end) {
- fprintf(stderr, "unterminated varint, unexpected end of buffer");
+ #ifdef PBF_USE_SETJMP
+ msg = "unterminated varint, unexpected end of buffer";
+ std::longjmp(jump_buffer, UNTERMINATED_VARINT);
+ #endif
exit(1);
}
result |= ((T)(byte = *data) & 0x7F) << bitpos;
@@ -84,7 +101,10 @@ T pbf::varint()
data++;
}
if (bitpos == 70 && (byte & 0x80)) {
- fprintf(stderr, "unterminated varint (too long)");
+ #ifdef PBF_USE_SETJMP
+ msg = "unterminated varint (too long)";
+ std::longjmp(jump_buffer, UNTERMINATED_VARINT);
+ #endif
exit(1);
}
@@ -133,14 +153,13 @@ bool pbf::boolean()
return *(bool *)(data - 1);
}
-
-template <typename T, typename... Args> T *pbf::message(const Args&... args)
-{
- uint32_t bytes = (uint32_t)varint();
- T *result = new T(data, bytes, args...);
- skipBytes(bytes);
- return result;
-}
+// template <typename T, typename... Args> T *pbf::message(const Args&... args)
+// {
+// uint32_t bytes = (uint32_t)varint();
+// T *result = new T(data, bytes, args...);
+// skipBytes(bytes);
+// return result;
+// }
void pbf::skip()
{
@@ -163,7 +182,12 @@ void pbf::skipValue(uint32_t val)
skipBytes(4);
break;
default:
- fprintf(stderr, "cannot skip unknown type %d", val & 0x7);
+ char text[32];
+ snprintf(text, 32, "cannot skip unknown type %d", val & 0x7);
+ #ifdef PBF_USE_SETJMP
+ msg = text;
+ std::longjmp(jump_buffer, UNKNOWN_TYPE);
+ #endif
exit(1);
}
}
@@ -172,7 +196,10 @@ void pbf::skipBytes(uint32_t bytes)
{
data += bytes;
if (data > end) {
- fprintf(stderr, "unexpected end of buffer");
+ #ifdef PBF_USE_SETJMP
+ msg = "unexpected end of buffer";
+ std::longjmp(jump_buffer, END_OF_BUFFER);
+ #endif
exit(1);
}
}
diff --git a/src/map/tile.cpp b/src/map/tile.cpp
index c04392af3a..ab9f2fe03b 100644
--- a/src/map/tile.cpp
+++ b/src/map/tile.cpp
@@ -12,25 +12,27 @@
using namespace llmr;
-uint64_t tile::toID(int32_t z, int32_t x, int32_t y, int32_t w) {
- w *= 2;
- if (w < 0) w = w * -1 -1;
- int32_t dim = 1 << z;
- return ((dim * dim * w + dim * y + x) * 32) + z;
-}
-
-vec4<int32_t> tile::fromID(uint64_t id) {
- vec4<int32_t> coord;
- coord.z = id % 32;
- int32_t dim = 1 << coord.z;
- int32_t xy = ((id - coord.z) / 32);
- coord.x = xy % dim;
- coord.y = ((xy - coord.x) / dim) % dim;
- coord.w = floor(xy / (dim * dim));
- if (coord.w % 2 != 0) coord.w = coord.w * -1 -1;
- coord.w /= 2;
- return coord;
-};
+// int64_t tile::toID(int32_t z, int32_t x, int32_t y, int32_t w) {
+// w *= 2;
+// if (w < 0) w = w * -1 -1;
+// int32_t dim = 1 << z;
+// return ((dim * dim * w + dim * y + x) * 32) + z;
+// }
+
+// vec4<int32_t> tile::fromID(int64_t id) {
+// vec4<int32_t> coord;
+// coord.z = id % 32;
+// int32_t dim = 1 << coord.z;
+// int64_t xy = ((id - coord.z) / 32);
+// coord.x = xy % dim;
+// coord.y = ((xy - coord.x) / dim) % dim;
+// coord.w = floor(xy / (dim * dim));
+// if (coord.w % 2 != 0) coord.w = coord.w * -1 -1;
+// coord.w /= 2;
+
+// fprintf(stderr, "tile: %d/%d/%d/%d\n", coord.z, coord.x, coord.y, coord.w);
+// return coord;
+// };
tile::tile(int32_t z, int32_t x, int32_t y)
: z(z),
@@ -42,6 +44,13 @@ tile::tile(int32_t z, int32_t x, int32_t y)
bytes(0) {
}
+tile::~tile() {
+ fprintf(stderr, "[%p] deleting tile %d/%d/%d\n", this, z, x, y);
+ if (this->data) {
+ free(this->data);
+ }
+}
+
void tile::setData(uint8_t *data, uint32_t bytes) {
this->data = (uint8_t *)malloc(bytes);
this->bytes = bytes;
@@ -50,12 +59,11 @@ void tile::setData(uint8_t *data, uint32_t bytes) {
void tile::cancel()
{
+ std::lock_guard<std::mutex> lock(mutex);
+
// TODO: thread safety
if (!cancelled) {
cancelled = true;
- if (loaded) {
- delete this;
- }
} else {
assert((!"logic error? multiple cancelleations"));
}
@@ -63,14 +71,24 @@ void tile::cancel()
bool tile::parse()
{
- if (cancelled) {
- delete this;
- return false;
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ if (cancelled) {
+ return false;
+ }
}
- fprintf(stderr, "[%p] parsing tile...\n", this);
+ // fprintf(stderr, "[%p] parsing tile [%d/%d/%d]...\n", this, z, x, y);
pbf tile(data, bytes);
+
+ int code = setjmp(tile.jump_buffer);
+ if (code > 0) {
+ fprintf(stderr, "[%p] parsing tile [%d/%d/%d]... failed: %s\n", this, z, x, y, tile.msg.c_str());
+ cancel();
+ return false;
+ }
+
while (tile.next()) {
if (tile.tag == 3) { // layer
uint32_t bytes = (uint32_t)tile.varint();
@@ -81,11 +99,13 @@ bool tile::parse()
}
}
- fprintf(stderr, "[%p] parsing tile...done\n", this);
+ // fprintf(stderr, "[%p] parsing tile [%d/%d/%d]... done\n", this, z, x, y);
- if (cancelled) {
- delete this;
- return false;
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ if (cancelled) {
+ return false;
+ }
}
loaded = true;
diff --git a/src/map/transform.cpp b/src/map/transform.cpp
index e31fad4233..6c5f902c86 100644
--- a/src/map/transform.cpp
+++ b/src/map/transform.cpp
@@ -52,8 +52,6 @@ void transform::scaleBy(double ds, double cx, double cy) {
scale *= ds;
x = (x * ds) + fx;
y = (y * ds) + fy;
-
- fprintf(stderr, "scale: %f, %f, %f\n", scale, x, y);
}
diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp
index 656d1fd645..a7ee1f034a 100644
--- a/src/renderer/painter.cpp
+++ b/src/renderer/painter.cpp
@@ -79,7 +79,7 @@ void painter::teardown() {
}
-void painter::changeMatrix(tile *tile) {
+void painter::changeMatrix(std::shared_ptr<tile> tile) {
assert(transform);
// Initialize projection matrix
@@ -97,7 +97,7 @@ void painter::clear() {
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
-void painter::render(tile *tile) {
+void painter::render(std::shared_ptr<tile> tile) {
changeMatrix(tile);
glDisable(GL_STENCIL_TEST);