diff --git a/.travis.yml b/.travis.yml index d9cd3a212..2d396c8e1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,8 +23,6 @@ before_install: install: - make setup -- rm -rf mapnik-packaging/out/packages - before_script: - if [[ ${CXX} == "g++" ]]; then export CXX="g++-4.8" ; fi @@ -41,7 +39,7 @@ script: #- make run-headless-test BUILDTYPE=${BUILDTYPE} notifications: -- hipchat: WB52YkcbCGMbNcStsGeaoRO7cyBSK4wX2ZHo2Y4b@GL + hipchat: WB52YkcbCGMbNcStsGeaoRO7cyBSK4wX2ZHo2Y4b@GL git: submodules: false diff --git a/bin/style.js b/bin/style.js index ffa326525..d851c1f16 100644 --- a/bin/style.js +++ b/bin/style.js @@ -1819,6 +1819,17 @@ module.exports = { "stops", {"z": 16, "val": 10}, {"z": 17, "val": 11} + ], + "hillshade_prerender": [ + "stops", + {"z": 11, "val": 0}, + {"z": 12, "val": 1} + ], + "hillshade_prerender_size": [ + "stops", + {"z": 11, "val": 1056}, + {"z": 12, "val": 512}, + {"z": 13, "val": 256} ] }, "classes": [ @@ -1972,8 +1983,8 @@ module.exports = { "hillshade_full_shadow": { "color": "#103", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", @@ -1987,8 +1998,8 @@ module.exports = { "hillshade_medium_shadow": { "color": "#206", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", @@ -2002,8 +2013,8 @@ module.exports = { "hillshade_full_highlight": { "color": "#fffff3", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", @@ -2017,8 +2028,8 @@ module.exports = { "hillshade_medium_highlight": { "color": "#ffd", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", @@ -2784,8 +2795,8 @@ module.exports = { "hillshade_full_shadow": { "color": "#103", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", @@ -2798,8 +2809,8 @@ module.exports = { "hillshade_medium_shadow": { "color": "#206", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", @@ -2812,8 +2823,8 @@ module.exports = { "hillshade_full_highlight": { "color": "#fdfdad", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", @@ -2827,8 +2838,8 @@ module.exports = { "hillshade_medium_highlight": { "color": "#ffe1b7", "antialias": false, - "prerender": true, - "prerender-size": 1024, + "prerender": "hillshade_prerender", + "prerender-size": "hillshade_prerender_size", "prerender-blur": 1, "opacity": [ "stops", diff --git a/common/curl_request.cpp b/common/curl_request.cpp index 40d94b956..7eae7fd95 100644 --- a/common/curl_request.cpp +++ b/common/curl_request.cpp @@ -190,7 +190,7 @@ void curl_perform(uv_poll_t *req, int /*status*/, int events) { } int handle_socket(CURL * /*easy*/, curl_socket_t s, int action, void * /*userp*/, void *socketp) { - curl_context *context = nullptr; + curl_context *context; if (action == CURL_POLL_IN || action == CURL_POLL_OUT) { if (socketp) { context = (curl_context *)socketp; @@ -199,9 +199,6 @@ int handle_socket(CURL * /*easy*/, curl_socket_t s, int action, void * /*userp*/ } curl_multi_assign(curl_multi, s, (void *)context); } - if (!context) { - throw std::runtime_error("unhandled action in socket handling"); - } switch (action) { case CURL_POLL_IN: diff --git a/common/glfw_view.cpp b/common/glfw_view.cpp index 5c623d725..43557ee4d 100644 --- a/common/glfw_view.cpp +++ b/common/glfw_view.cpp @@ -73,8 +73,17 @@ void GLFWView::key(GLFWwindow *window, int key, int /*scancode*/, int action, in view->map->resetPosition(); break; case GLFW_KEY_R: - if (!mods) - view->map->toggleStyle(); + if (!mods) { + std::set newAppliedClasses; + if (view->map->getAppliedClasses().count("night")) { + newAppliedClasses.insert("default"); + } else { + newAppliedClasses.insert("default"); + newAppliedClasses.insert(newAppliedClasses.end(), "night"); + } + view->map->setDefaultTransitionDuration(300); + view->map->setAppliedClasses(newAppliedClasses); + } break; case GLFW_KEY_N: if (!mods) diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index d5d11dde8..abcaa159d 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -53,7 +53,6 @@ public: void resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height); // Styling - void toggleStyle(); void setAppliedClasses(std::set appliedClasses); std::set getAppliedClasses() const; void setDefaultTransitionDuration(uint64_t duration_milliseconds = 0); diff --git a/include/llmr/renderer/painter.hpp b/include/llmr/renderer/painter.hpp index 0345c9c00..104f4c9bd 100644 --- a/include/llmr/renderer/painter.hpp +++ b/include/llmr/renderer/painter.hpp @@ -85,9 +85,9 @@ public: void renderText(TextBucket& bucket, const std::string& layer_name, const Tile::ID& id); void renderRaster(RasterBucket& bucket, const std::string& layer_name, const Tile::ID& id); - void preparePrerender(const GenericProperties &properties); - void finishPrerender(const GenericProperties &properties); - void renderPrerenderedTexture(Bucket &bucket, const GenericProperties &properties); + void preparePrerender(PrerenderedTexture &texture); + void finishPrerender(PrerenderedTexture &texture); + void renderPrerenderedTexture(PrerenderedTexture &texture, const GenericProperties &properties); void resize(); diff --git a/include/llmr/renderer/prerendered_texture.hpp b/include/llmr/renderer/prerendered_texture.hpp index 4b163ac70..b109e397c 100644 --- a/include/llmr/renderer/prerendered_texture.hpp +++ b/include/llmr/renderer/prerendered_texture.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace llmr { @@ -10,7 +11,7 @@ class Painter; class PrerenderedTexture : private util::noncopyable { public: - PrerenderedTexture(uint16_t size); + PrerenderedTexture(const PrerenderProperties &properties); ~PrerenderedTexture(); void bindTexture(); @@ -21,8 +22,10 @@ public: void blur(Painter& painter, uint16_t passes); +public: + const PrerenderProperties properties; + private: - const uint16_t size; GLint previous_fbo = 0; GLuint fbo = 0; GLuint texture = 0; diff --git a/include/llmr/style/properties.hpp b/include/llmr/style/properties.hpp index d0bc3b2d4..487f2d6c6 100644 --- a/include/llmr/style/properties.hpp +++ b/include/llmr/style/properties.hpp @@ -93,10 +93,16 @@ struct GenericClass { boost::optional translateAnchor; boost::optional opacity; boost::optional opacity_transition; - boost::optional prerender; - boost::optional prerenderBuffer; - boost::optional prerenderSize; - boost::optional prerenderBlur; + boost::optional prerender; + boost::optional prerenderBuffer; + boost::optional prerenderSize; + boost::optional prerenderBlur; +}; + +struct PrerenderProperties { + float buffer = 1.0f / 32.0f; + uint16_t size = 256; + uint16_t blur = 0; }; struct GenericProperties { @@ -104,10 +110,25 @@ struct GenericProperties { std::array translate = {{ 0, 0 }}; TranslateAnchor translateAnchor = TranslateAnchor::Map; float opacity = 1.0; - bool prerender = false; - float prerenderBuffer = 1.0f / 32.0f; - uint16_t prerenderSize = 256; - uint16_t prerenderBlur = 0; + + // These are unresolved properties because the value here is per tile, so it might differ. + boost::optional prerender; + boost::optional prerenderBuffer; + boost::optional prerenderSize; + boost::optional prerenderBlur; + + inline bool getPrerender(int8_t z) const { + return prerender && prerender.get().evaluate(z); + } + + // Obtains prerender properties by integer zoom level. + inline PrerenderProperties getPrerenderProperties(int8_t z) const { + PrerenderProperties props; + if (prerenderBuffer) props.buffer = prerenderBuffer.get().evaluate(z); + if (prerenderSize) props.size = prerenderSize.get().evaluate(z); + if (prerenderBlur) props.blur = prerenderBlur.get().evaluate(z); + return props; + } virtual bool isVisible() const { if (!enabled) { return false; } diff --git a/ios/mapbox-gl-cocoa b/ios/mapbox-gl-cocoa index 31b708821..687d84e7c 160000 --- a/ios/mapbox-gl-cocoa +++ b/ios/mapbox-gl-cocoa @@ -1 +1 @@ -Subproject commit 31b708821de6e8a539ff3a2353202850c253da94 +Subproject commit 687d84e7c907f94b45cd364e8851d36d738937f4 diff --git a/src/map/map.cpp b/src/map/map.cpp index dd83c4edb..252c46fe5 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -387,29 +387,6 @@ bool Map::getDebug() const { return debug; } -void Map::toggleStyle() { - setDefaultTransitionDuration(300); - style->cancelTransitions(); - - if (style->appliedClasses.size() == 1) { - for (auto source_it = style->classes.begin(); source_it != style->classes.end(); source_it++) { - if (source_it->first != "default") { - style->appliedClasses.insert(source_it->first); - break; - } - } - } else { - for (auto source_it = style->classes.begin(); source_it != style->classes.end(); source_it++) { - if (source_it->first != "default") { - style->appliedClasses.erase(source_it->first); - break; - } - } - } - - update(); -} - void Map::setAppliedClasses(std::set appliedClasses) { style->cancelTransitions(); diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 0cc137013..fd5b1a334 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -152,18 +152,17 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons : defaultFillProperties; if (!properties.enabled) return; - - if (properties.prerender) { + if (properties.prerender && properties.getPrerender(id.z)) { if (pass == Translucent) { // Buffer value around the 0..4096 extent that will be drawn into the 256x256 pixel // texture. We later scale the texture so that the actual bounds will align with this // tile's bounds. The reason we do this is so that the - if (!bucket.prerendered) { - bucket.prerendered = std::make_unique(properties.prerenderSize); + const PrerenderProperties prerender = properties.getPrerenderProperties(id.z); + bucket.prerendered = std::make_unique(prerender); bucket.prerendered->bindFramebuffer(); - preparePrerender(properties); + preparePrerender(*bucket.prerendered); const FillProperties modifiedProperties = [&]{ FillProperties modifiedProperties = properties; @@ -173,7 +172,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons // When drawing the fill, we want to draw a buffer around too, so we // essentially downscale everyting, and then upscale it later when rendering. - const int buffer = 4096 * properties.prerenderBuffer; + const int buffer = prerender.buffer * 4096.0f; const mat4 vtxMatrix = [&]{ mat4 vtxMatrix; matrix::ortho(vtxMatrix, -buffer, 4096 + buffer, -4096 - buffer, buffer, 0, 1); @@ -187,17 +186,16 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons setTranslucent(); renderFill(bucket, modifiedProperties, id, vtxMatrix); - - if (properties.prerenderBlur > 0) { - bucket.prerendered->blur(*this, properties.prerenderBlur); + if (prerender.blur > 0) { + bucket.prerendered->blur(*this, prerender.blur); } // RESET STATE bucket.prerendered->unbindFramebuffer(); - finishPrerender(properties); + finishPrerender(*bucket.prerendered); } - renderPrerenderedTexture(bucket, properties); + renderPrerenderedTexture(*bucket.prerendered, properties); } } else { const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); diff --git a/src/renderer/painter_prerender.cpp b/src/renderer/painter_prerender.cpp index 7d4f7f9d9..6d748c7c4 100644 --- a/src/renderer/painter_prerender.cpp +++ b/src/renderer/painter_prerender.cpp @@ -2,7 +2,7 @@ using namespace llmr; -void Painter::preparePrerender(const GenericProperties &properties) { +void Painter::preparePrerender(PrerenderedTexture &texture) { glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); @@ -13,18 +13,18 @@ void Painter::preparePrerender(const GenericProperties &properties) { #endif glClear(GL_COLOR_BUFFER_BIT); - glViewport(0, 0, properties.prerenderSize, properties.prerenderSize); + glViewport(0, 0, texture.properties.size, texture.properties.size); } -void Painter::finishPrerender(const GenericProperties &properties) { +void Painter::finishPrerender(PrerenderedTexture &texture) { glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); glViewport(0, 0, gl_viewport[0], gl_viewport[1]); } -void Painter::renderPrerenderedTexture(Bucket &bucket, const GenericProperties &properties) { - const int buffer = 4096 * properties.prerenderBuffer; +void Painter::renderPrerenderedTexture(PrerenderedTexture &texture, const GenericProperties &properties) { + const int buffer = texture.properties.buffer * 4096.0f; // draw the texture on a quad useProgram(rasterShader->program); @@ -37,7 +37,7 @@ void Painter::renderPrerenderedTexture(Bucket &bucket, const GenericProperties & rasterShader->setImage(0); rasterShader->setBuffer(buffer); rasterShader->setOpacity(properties.opacity); - bucket.prerendered->bindTexture(); + texture.bindTexture(); coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); } diff --git a/src/renderer/prerendered_texture.cpp b/src/renderer/prerendered_texture.cpp index 408f433be..7fc27ec71 100644 --- a/src/renderer/prerendered_texture.cpp +++ b/src/renderer/prerendered_texture.cpp @@ -4,8 +4,8 @@ using namespace llmr; -PrerenderedTexture::PrerenderedTexture(uint16_t size) - : size(size) { +PrerenderedTexture::PrerenderedTexture(const PrerenderProperties &properties) + : properties(properties) { } PrerenderedTexture::~PrerenderedTexture() { @@ -28,11 +28,6 @@ void PrerenderedTexture::bindTexture() { } glBindTexture(GL_TEXTURE_2D, texture); - - // if (!mipmapped) { - // glGenerateMipmap(GL_TEXTURE_2D); - // mipmapped = true; - // } } void PrerenderedTexture::bindFramebuffer() { @@ -45,7 +40,7 @@ void PrerenderedTexture::bindFramebuffer() { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, properties.size, properties.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); } @@ -95,7 +90,7 @@ void PrerenderedTexture::blur(Painter& painter, uint16_t passes) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, properties.size, properties.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, 0); @@ -113,7 +108,7 @@ void PrerenderedTexture::blur(Painter& painter, uint16_t passes) { #endif glClear(GL_COLOR_BUFFER_BIT); - painter.gaussianShader->setOffset({{ 1.0f / float(size), 0 }}); + painter.gaussianShader->setOffset({{ 1.0f / float(properties.size), 0 }}); glBindTexture(GL_TEXTURE_2D, original_texture); painter.coveringGaussianArray.bind(*painter.gaussianShader, painter.tileStencilBuffer, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)painter.tileStencilBuffer.index()); @@ -127,7 +122,7 @@ void PrerenderedTexture::blur(Painter& painter, uint16_t passes) { #endif glClear(GL_COLOR_BUFFER_BIT); - painter.gaussianShader->setOffset({{ 0, 1.0f / float(size) }}); + painter.gaussianShader->setOffset({{ 0, 1.0f / float(properties.size) }}); glBindTexture(GL_TEXTURE_2D, secondary_texture); painter.coveringGaussianArray.bind(*painter.gaussianShader, painter.tileStencilBuffer, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)painter.tileStencilBuffer.index()); diff --git a/src/style/style.cpp b/src/style/style.cpp index 9ae0b273f..a0c8a1e57 100644 --- a/src/style/style.cpp +++ b/src/style/style.cpp @@ -51,21 +51,10 @@ void Style::cascadeProperties(GenericProperties &properties, const GenericClass& } } - if (klass.prerender) { - properties.prerender = klass.prerender.get(); - } - - if (klass.prerenderBuffer) { - properties.prerenderBuffer = klass.prerenderBuffer.get(); - } - - if (klass.prerenderSize) { - properties.prerenderSize = klass.prerenderSize.get(); - } - - if (klass.prerenderBlur) { - properties.prerenderBlur = klass.prerenderBlur.get(); - } + properties.prerender = klass.prerender; + properties.prerenderBuffer = klass.prerenderBuffer; + properties.prerenderSize = klass.prerenderSize; + properties.prerenderBlur = klass.prerenderBlur; } diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index 83d0eb256..2b6c0e3f2 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -557,19 +557,19 @@ void StyleParser::parseGenericClass(GenericClass &klass, JSVal value) { } if (value.HasMember("prerender")) { - klass.prerender = parseBoolean(value["prerender"]); + klass.prerender = parseFunction(value["prerender"]); } if (value.HasMember("prerender-buffer")) { - klass.prerenderBuffer = toNumber(parseValue(value["prerender-buffer"])); + klass.prerenderBuffer = parseFunction(value["prerender-buffer"]); } if (value.HasMember("prerender-size")) { - klass.prerenderSize = toNumber(parseValue(value["prerender-size"])); + klass.prerenderSize = parseFunction(value["prerender-size"]); } if (value.HasMember("prerender-blur")) { - klass.prerenderBlur = toNumber(parseValue(value["prerender-blur"])); + klass.prerenderBlur = parseFunction(value["prerender-blur"]); } }