Calculate clip IDs with a huffman prefix tree

This changes the clip IDs from sequential to a huffman prefix tree, meaning that
parent tiles share the same prefix with child tiles (but are shorter). This allows
us to use the same checkerboard pattern to draw all tiles.

TODO:
- make sure we're not overflowing the 8 bit limit of the stencil buffer
- draw all checkerboard fields at the same time, with one draw call
- fix raster drawing (fading, clipping)

refs #132
This commit is contained in:
Konstantin Käfer
2014-05-09 18:10:28 +02:00
parent 70a7ba81f3
commit 0bfd7b0f43
32 changed files with 1129 additions and 290 deletions

View File

@@ -1,33 +1,22 @@
#include <llmr/map/tile_data.hpp>
#include <llmr/map/tile_parser.hpp>
#include <llmr/map/map.hpp>
#include <llmr/geometry/fill_buffer.hpp>
#include <llmr/geometry/line_buffer.hpp>
#include <llmr/geometry/point_buffer.hpp>
#include <llmr/geometry/text_buffer.hpp>
#include <llmr/geometry/elements_buffer.hpp>
#include <llmr/util/raster.hpp>
#include <llmr/util/string.hpp>
#include <llmr/util/uv.hpp>
using namespace llmr;
TileData::TileData(Tile::ID id, Map &map, const std::string url, const bool is_raster)
TileData::TileData(Tile::ID id, Map &map, const std::string url)
: id(id),
state(State::initial),
raster(),
map(map),
url(url),
is_raster(is_raster),
map(map) {
debugBucket(debugFontBuffer) {
// Initialize tile debug coordinates
const std::string str = util::sprintf<32>("%d/%d/%d", id.z, id.x, id.y);
debugFontBuffer.addText(str.c_str(), 50, 200, 5);
}
TileData::~TileData() {
map.getGlyphAtlas().removeGlyphs((uint64_t)id);
cancel();
}
@@ -51,7 +40,7 @@ void TileData::request() {
tile->data.swap(res->body);
// Schedule tile parsing in another thread
tile->scheduleParsing();
tile->reparse();
} else {
fprintf(stderr, "[%s] tile loading failed: %d, %s\n", tile->url.c_str(), res->code, res->error_message.c_str());
}
@@ -65,7 +54,7 @@ void TileData::cancel() {
}
}
void TileData::scheduleParsing() {
void TileData::reparse() {
// We're creating a new work request. The work request deletes itself after it executed
// the after work handler
new uv::work<std::shared_ptr<TileData>>(
@@ -74,24 +63,3 @@ void TileData::scheduleParsing() {
[](std::shared_ptr<TileData> &tile) { tile->map.update(); },
shared_from_this());
}
void TileData::parse() {
if (state != State::loaded) {
return;
}
try {
// Parsing creates state that is encapsulated in TileParser. While parsing,
// the TileParser object writes results into this objects. All other state
// is going to be discarded afterwards.
TileParser parser(data, *this, map.getStyle(), map.getGlyphAtlas(), is_raster);
} catch (const std::exception& ex) {
fprintf(stderr, "[%p] exception [%d/%d/%d]... failed: %s\n", this, id.z, id.x, id.y, ex.what());
cancel();
return;
}
if (state != State::obsolete) {
state = State::parsed;
}
}