diff options
author | Leith Bade <leith@mapbox.com> | 2015-01-15 11:39:50 +1100 |
---|---|---|
committer | Leith Bade <leith@mapbox.com> | 2015-01-15 11:39:50 +1100 |
commit | b7cc6bfaa686cfed1f0ac441693c5c070242343d (patch) | |
tree | f97b38dcdfbe67d6159c257d81c85380ea2a0347 /src | |
parent | ddbfcada2776a86f8efb6cabba85f6c3a6633d38 (diff) | |
parent | c6ca57045fb373d4fd76d1ec228bd35a518d06e8 (diff) | |
download | qtlocation-mapboxgl-b7cc6bfaa686cfed1f0ac441693c5c070242343d.tar.gz |
Merge branch 'master' of github.com:mapbox/mapbox-gl-native into android-mason
Conflicts:
src/mbgl/shader/shader.cpp
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/map/map.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.cpp | 53 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/shader/shader.cpp | 71 | ||||
-rw-r--r-- | src/mbgl/util/merge_lines.hpp | 107 |
5 files changed, 182 insertions, 61 deletions
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index f5948fbb22..d135ce0da8 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -301,6 +301,8 @@ void Map::run() { mode = Mode::None; fileSource.clearLoop(); } + + terminate(); } void Map::checkForPause() { @@ -329,8 +331,9 @@ void Map::rerender() { } else if (mode == Mode::Continuous) { // We only send render events if we want to continuously update the map // (== async rendering). - assert(asyncRender); - asyncRender->send(); + if (asyncRender) { + asyncRender->send(); + } } } @@ -350,7 +353,9 @@ void Map::swapped() { void Map::terminate() { assert(painter); + view.activate(); painter->terminate(); + view.deactivate(); } #pragma mark - Setup diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 0eadacec5a..c6a7c8c4e1 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -16,6 +16,7 @@ #include <mbgl/util/utf.hpp> #include <mbgl/util/token.hpp> #include <mbgl/util/math.hpp> +#include <mbgl/util/merge_lines.hpp> namespace mbgl { @@ -85,11 +86,31 @@ std::vector<SymbolFeature> SymbolBucket::processFeatures(const VectorTileLayer & } if (ft.label.length() || ft.sprite.length()) { - ft.geometry = feature.geometry; + + auto &multiline = ft.geometry; + + // Decode line + Geometry::command cmd; + pbf geom(feature.geometry); + Geometry geometry(geom); + bool first = true; + int32_t x, y; + while ((cmd = geometry.next(x, y)) != Geometry::end) { + if (first || cmd == Geometry::move_to) { + multiline.emplace_back(); + first = false; + } + multiline.back().emplace_back(x, y); + } + features.push_back(std::move(ft)); } } + if (properties.placement == PlacementType::Line) { + util::mergeLines(features); + } + glyphStore.waitForGlyphRanges(properties.text.font, ranges); sprite.waitUntilLoaded(); @@ -146,6 +167,8 @@ void SymbolBucket::addFeatures(const VectorTileLayer &layer, const FilterExpress const FontStack &fontStack = glyphStore.getFontStack(properties.text.font); for (const SymbolFeature &feature : features) { + if (!feature.geometry.size()) continue; + Shaping shaping; Rect<uint16_t> image; GlyphPositions face; @@ -181,32 +204,12 @@ void SymbolBucket::addFeatures(const VectorTileLayer &layer, const FilterExpress // if either shaping or icon position is present, add the feature if (shaping.size() || image) { - addFeature(feature.geometry, shaping, face, image); - } - } -} - -void SymbolBucket::addFeature(const pbf &geom_pbf, const Shaping &shaping, - const GlyphPositions &face, const Rect<uint16_t> &image) { - // Decode all lines. - std::vector<Coordinate> line; - Geometry::command cmd; - - Coordinate coord; - pbf geom(geom_pbf); - Geometry geometry(geom); - int32_t x, y; - while ((cmd = geometry.next(x, y)) != Geometry::end) { - if (cmd == Geometry::move_to) { - if (!line.empty()) { - addFeature(line, shaping, face, image); - line.clear(); + for (const std::vector<Coordinate> &line : feature.geometry) { + if (line.size()) { + addFeature(line, shaping, face, image); + } } } - line.emplace_back(x, y); - } - if (line.size()) { - addFeature(line, shaping, face, image); } } diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index dd596b1a00..bc148579fa 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -30,7 +30,7 @@ class FontStack; class SymbolFeature { public: - pbf geometry; + std::vector<std::vector<Coordinate>> geometry; std::u32string label; std::string sprite; }; @@ -77,7 +77,6 @@ private: std::vector<SymbolFeature> processFeatures(const VectorTileLayer &layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite); - void addFeature(const pbf &geom_pbf, const Shaping &shaping, const GlyphPositions &face, const Rect<uint16_t> &image); void addFeature(const std::vector<Coordinate> &line, const Shaping &shaping, const GlyphPositions &face, const Rect<uint16_t> &image); diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/shader/shader.cpp index 6e52126aa9..5eb354f852 100644 --- a/src/mbgl/shader/shader.cpp +++ b/src/mbgl/shader/shader.cpp @@ -27,40 +27,38 @@ Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSo // Load binary shader if it exists bool skipCompile = false; if (!binaryFileName.empty() && (gl::ProgramBinary != nullptr)) { - std::ifstream binaryFile(binaryFileName, std::ios::in | std::ios::binary); + try { + std::ifstream binaryFile(binaryFileName, std::ios::in | std::ios::binary); + binaryFile.exceptions(std::ifstream::failbit | std::ifstream::badbit | std::ifstream::eofbit); - GLsizei binaryLength; - GLenum binaryFormat; - binaryFile.read(reinterpret_cast<char *>(&binaryLength), sizeof(binaryLength)); - binaryFile.read(reinterpret_cast<char *>(&binaryFormat), sizeof(binaryFormat)); + GLsizei binaryLength; + GLenum binaryFormat; + binaryFile.read(reinterpret_cast<char *>(&binaryLength), sizeof(binaryLength)); + binaryFile.read(reinterpret_cast<char *>(&binaryFormat), sizeof(binaryFormat)); - GLint numBinaryFormats; - MBGL_CHECK_ERROR(glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &numBinaryFormats)); + GLint numBinaryFormats; + MBGL_CHECK_ERROR(glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &numBinaryFormats)); - std::unique_ptr<GLenum[]> validBinaryFormats = mbgl::util::make_unique<GLenum[]>(numBinaryFormats); - MBGL_CHECK_ERROR(glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, reinterpret_cast<GLint *>(validBinaryFormats.get()))); + std::unique_ptr<GLenum[]> validBinaryFormats = mbgl::util::make_unique<GLenum[]>(numBinaryFormats); + MBGL_CHECK_ERROR(glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, reinterpret_cast<GLint *>(validBinaryFormats.get()))); - bool validBinaryFormat = false; - for (GLint i = 0; i < numBinaryFormats; i++) { - if (validBinaryFormats[i] == binaryFormat) { - validBinaryFormat = true; + bool validBinaryFormat = false; + for (GLint i = 0; i < numBinaryFormats; i++) { + if (validBinaryFormats[i] == binaryFormat) { + validBinaryFormat = true; + } + } + if (!validBinaryFormat) { + throw std::runtime_error("Trying load program binary with an invalid binaryFormat!"); } - } - if (!validBinaryFormat) { - Log::Error(Event::OpenGL, "Trying load program binary with an invalid binaryFormat!"); - } - - if (binaryLength == 0) { - Log::Error(Event::OpenGL, "Trying load program binary with a zero length binary!"); - } - if (validBinaryFormat && (binaryLength != 0)) { + if (binaryLength == 0) { + throw std::runtime_error("Trying load program binary with a zero length binary!"); + } std::unique_ptr<char[]> binary = mbgl::util::make_unique<char[]>(binaryLength); binaryFile.read(binary.get(), binaryLength); - binaryFile.close(); - Log::Error(Event::OpenGL, "glProgramBinary(%u, %u, %u, %u)", program, binaryFormat, binary.get(), binaryLength); MBGL_CHECK_ERROR(gl::ProgramBinary(program, binaryFormat, binary.get(), binaryLength)); // Check if the binary was valid @@ -69,8 +67,8 @@ Shader::Shader(const char *name_, const GLchar *vertSource, const GLchar *fragSo if (status == GL_TRUE) { skipCompile = true; } - } else { - binaryFile.close(); + } catch(std::exception& e) { + Log::Error(Event::Shader, "Loading binary shader failed!"); // Delete the bad file std::remove(binaryFileName.c_str()); @@ -214,12 +212,21 @@ Shader::~Shader() { Log::Error(Event::OpenGL, "glGetProgramBinary(%u, %u, nullptr, %u, %u)", program, binaryLength, binaryFormat, binary.get()); - // Write the binary to a file - std::ofstream binaryFile(binaryFileName, std::ios::out | std::ios::trunc | std::ios::binary); - binaryFile.write(reinterpret_cast<char *>(&binaryLength), sizeof(binaryLength)); - binaryFile.write(reinterpret_cast<char *>(&binaryFormat), sizeof(binaryFormat)); - binaryFile.write(binary.get(), binaryLength); - binaryFile.close(); + try { + // Write the binary to a file + std::ofstream binaryFile(binaryFileName, std::ios::out | std::ios::trunc | std::ios::binary); + binaryFile.exceptions(std::ofstream::failbit | std::ofstream::badbit | std::ofstream::eofbit); + + binaryFile.write(reinterpret_cast<char *>(&binaryLength), sizeof(binaryLength)); + binaryFile.write(reinterpret_cast<char *>(&binaryFormat), sizeof(binaryFormat)); + binaryFile.write(binary.get(), binaryLength); + + } catch(std::exception& e) { + Log::Error(Event::Shader, "Saving binary shader failed!"); + + // Delete the bad file + std::remove(binaryFileName.c_str()); + } } } diff --git a/src/mbgl/util/merge_lines.hpp b/src/mbgl/util/merge_lines.hpp new file mode 100644 index 0000000000..e0dd4c6415 --- /dev/null +++ b/src/mbgl/util/merge_lines.hpp @@ -0,0 +1,107 @@ +#ifndef MBGL_UTIL_MERGELINES +#define MBGL_UTIL_MERGELINES + +#include <map> +#include <string> +#include <vector> +#include <sstream> +#include <mbgl/renderer/symbol_bucket.hpp> + + +namespace mbgl { +namespace util { + +unsigned int mergeFromRight( + std::vector<SymbolFeature> &features, + std::map<std::string,unsigned int> &rightIndex, + std::map<std::string,unsigned int>::iterator left, + std::string &rightKey, + std::vector<std::vector<Coordinate>> &geom) { + + unsigned int index = left->second; + rightIndex.erase(left); + rightIndex[rightKey] = index; + features[index].geometry[0].pop_back(); + features[index].geometry[0].insert(features[index].geometry[0].end(), geom[0].begin(), geom[0].end()); + geom[0].clear(); + return index; +} + +unsigned int mergeFromLeft( + std::vector<SymbolFeature> &features, + std::map<std::string,unsigned int> &leftIndex, + std::string &leftKey, + std::map<std::string,unsigned int>::iterator right, + std::vector<std::vector<Coordinate>> &geom) { + + unsigned int index = right->second; + leftIndex.erase(right); + leftIndex[leftKey] = index; + geom[0].pop_back(); + geom[0].insert(geom[0].end(), features[index].geometry[0].begin(), features[index].geometry[0].end()); + features[index].geometry[0].clear(); + std::swap(features[index].geometry[0], geom[0]); + return index; +} + +std::string getKey(const std::u32string &text, const std::vector<std::vector<Coordinate>> &geom, bool onRight) { + const Coordinate &coord = onRight ? geom[0].back() : geom[0].front(); + std::ostringstream key; + for (const char32_t &c : text) { + key << (char)c; + } + key << ":" << coord.x << ":" << coord.y; + return key.str(); +} + + +void mergeLines(std::vector<SymbolFeature> &features) { + + std::map<std::string,unsigned int> leftIndex; + std::map<std::string,unsigned int> rightIndex; + + for (unsigned int k = 0; k < features.size(); k++) { + SymbolFeature &feature = features[k]; + std::vector<std::vector<Coordinate>> &geometry = feature.geometry; + + if (!feature.label.length()) { + continue; + } + + std::string leftKey = getKey(feature.label, geometry, false); + std::string rightKey = getKey(feature.label, geometry, true); + + auto left = rightIndex.find(leftKey); + auto right = leftIndex.find(rightKey); + + if ((left != rightIndex.end()) && (right != leftIndex.end()) && (left->second != right->second)) { + // found lines with the same text adjacent to both ends of the current line, merge all three + unsigned int j = mergeFromLeft(features, leftIndex, leftKey, right, geometry); + unsigned int i = mergeFromRight(features, rightIndex, left, rightKey, features[j].geometry); + + leftIndex.erase(leftKey); + rightIndex.erase(rightKey); + rightIndex[getKey(feature.label, features[i].geometry, true)] = i; + + } else if (left != rightIndex.end()) { + // found mergeable line adjacent to the start of the current line, merge + mergeFromRight(features, rightIndex, left, rightKey, geometry); + + } else if (right != leftIndex.end()) { + // found mergeable line adjacent to the end of the current line, merge + mergeFromLeft(features, leftIndex, leftKey, right, geometry); + + } else { + // no adjacent lines, add as a new item + leftIndex[leftKey] = k; + rightIndex[rightKey] = k; + } + + } + +} + +} // end namespace util +} // end namespace mbgl + +#endif |