From 0ea8a37cb081302707c7815f3df5745bd3d6eef3 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 14 Jul 2015 15:14:39 +0300 Subject: [PATCH] Unify default transition values in MapData Relevant changes: - Added 'defaultFadeDuration' and 'defaultTransitionDelay' to MapData; - Painter & StyleParser now receives a reference to MapData; - As previously seen on the code: 300ms is the default fade duration and 0ms is the default transition duration; - We no longer pass the current time point to Style, since it now uses MapData.animationTime, which gets updated in MapContext::update(). - Updated StyleParser check to use a mock MapData; --- src/mbgl/map/map_context.cpp | 14 +++------ src/mbgl/map/map_data.hpp | 28 +++++++++++++++-- src/mbgl/renderer/painter.cpp | 5 ++-- src/mbgl/renderer/painter.hpp | 4 +-- src/mbgl/renderer/painter_debug.cpp | 7 +++-- src/mbgl/renderer/painter_line.cpp | 11 +++---- src/mbgl/renderer/painter_symbol.cpp | 5 ++-- .../style/piecewisefunction_properties.hpp | 1 - src/mbgl/style/property_transition.hpp | 2 ++ src/mbgl/style/style.cpp | 19 ++++++------ src/mbgl/style/style.hpp | 6 ++-- src/mbgl/style/style_parser.cpp | 30 ++++++++++--------- src/mbgl/style/style_parser.hpp | 5 +++- test/miscellaneous/style_parser.cpp | 9 +++++- 14 files changed, 88 insertions(+), 58 deletions(-) diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 7f2fe4e98..23bb5f590 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -254,21 +254,15 @@ void MapContext::update() { return; } - const TimePoint now = Clock::now(); - - data.setAnimationTime(now); - - if (updated & static_cast(Update::DefaultTransitionDuration)) { - style->setDefaultTransitionDuration(data.getDefaultTransitionDuration()); - } + data.setAnimationTime(Clock::now()); if (updated & static_cast(Update::Classes)) { - style->cascade(data.getClasses(), now); + style->cascade(); } if (updated & static_cast(Update::Classes) || updated & static_cast(Update::Zoom)) { - style->recalculate(transformState.getNormalizedZoom(), now); + style->recalculate(transformState.getNormalizedZoom()); } style->update(transformState, *texturePool); @@ -330,7 +324,7 @@ MapContext::RenderResult MapContext::renderSync(const TransformState& state, con glObjectStore.performCleanup(); if (!painter) { - painter = std::make_unique(data.pixelRatio); + painter = std::make_unique(data); painter->setup(); } diff --git a/src/mbgl/map/map_data.hpp b/src/mbgl/map/map_data.hpp index 1703aff8c..aadc8dcd6 100644 --- a/src/mbgl/map/map_data.hpp +++ b/src/mbgl/map/map_data.hpp @@ -20,10 +20,14 @@ class MapData { using Lock = std::lock_guard; public: - inline MapData(MapMode mode_, const float pixelRatio_) : mode(mode_), pixelRatio(pixelRatio_) { + inline MapData(MapMode mode_, const float pixelRatio_) + : mode(mode_) + , pixelRatio(pixelRatio_) + , animationTime(Duration::zero()) + , defaultFadeDuration(std::chrono::milliseconds(300)) + , defaultTransitionDuration(Duration::zero()) + , defaultTransitionDelay(Duration::zero()) { assert(pixelRatio > 0); - setAnimationTime(TimePoint::min()); - setDefaultTransitionDuration(Duration::zero()); } // Adds the class if it's not yet set. Returns true when it added the class, and false when it @@ -73,6 +77,14 @@ public: animationTime = timePoint.time_since_epoch(); }; + inline Duration getDefaultFadeDuration() const { + return defaultFadeDuration; + } + + inline void setDefaultFadeDuration(const Duration& duration) { + defaultFadeDuration = duration; + } + inline Duration getDefaultTransitionDuration() const { return defaultTransitionDuration; } @@ -81,6 +93,14 @@ public: defaultTransitionDuration = duration; } + inline Duration getDefaultTransitionDelay() const { + return defaultTransitionDelay; + } + + inline void setDefaultTransitionDelay(const Duration& delay) { + defaultTransitionDelay = delay; + } + util::exclusive getAnnotationManager() { return util::exclusive( &annotationManager, @@ -101,7 +121,9 @@ private: std::atomic debug { false }; std::atomic collisionDebug { false }; std::atomic animationTime; + std::atomic defaultFadeDuration; std::atomic defaultTransitionDuration; + std::atomic defaultTransitionDelay; // TODO: make private public: diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 77ee868c3..7570b6a74 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -41,14 +42,14 @@ using namespace mbgl; -Painter::Painter(const float pixelRatio_) : pixelRatio(pixelRatio_) { +Painter::Painter(MapData& data_) : data(data_) { } Painter::~Painter() { } bool Painter::needsAnimation() const { - return frameHistory.needsAnimation(std::chrono::milliseconds(300)); + return frameHistory.needsAnimation(data.getDefaultFadeDuration()) || state.isChanging(); } void Painter::setup() { diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 3719b7f2a..869aaa49c 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -81,7 +81,7 @@ struct RenderItem { class Painter : private util::noncopyable { public: - Painter(float pixelRatio); + Painter(MapData& data); ~Painter(); void setup(); @@ -191,7 +191,7 @@ public: }(); private: - const float pixelRatio; + MapData& data; TransformState state; FrameData frame; diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp index b5d9e343e..aa3fcba5d 100644 --- a/src/mbgl/renderer/painter_debug.cpp +++ b/src/mbgl/renderer/painter_debug.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,7 @@ void Painter::renderDebugText(DebugBucket& bucket, const mat4 &matrix) { // Draw white outline plainShader->u_color = {{ 1.0f, 1.0f, 1.0f, 1.0f }}; - lineWidth(4.0f * pixelRatio); + lineWidth(4.0f * data.pixelRatio); bucket.drawLines(*plainShader); #ifndef GL_ES_VERSION_2_0 @@ -39,7 +40,7 @@ void Painter::renderDebugText(DebugBucket& bucket, const mat4 &matrix) { // Draw black text. plainShader->u_color = {{ 0.0f, 0.0f, 0.0f, 1.0f }}; - lineWidth(2.0f * pixelRatio); + lineWidth(2.0f * data.pixelRatio); bucket.drawLines(*plainShader); config.depthTest = true; @@ -60,6 +61,6 @@ void Painter::renderDebugFrame(const mat4 &matrix) { // draw tile outline tileBorderArray.bind(*plainShader, tileBorderBuffer, BUFFER_OFFSET(0)); plainShader->u_color = {{ 1.0f, 0.0f, 0.0f, 1.0f }}; - lineWidth(4.0f * pixelRatio); + lineWidth(4.0f * data.pixelRatio); MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index())); } diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 5f5a89d41..1ef921410 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const // the distance over which the line edge fades out. // Retina devices need a smaller distance to avoid aliasing. - float antialiasing = 1.0 / pixelRatio; + float antialiasing = 1.0 / data.pixelRatio; float blur = properties.blur + antialiasing; float edgeWidth = properties.width / 2.0; @@ -61,7 +62,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const linesdfShader->u_matrix = vtxMatrix; linesdfShader->u_exmatrix = extrudeMatrix; linesdfShader->u_linewidth = {{ outset, inset }}; - linesdfShader->u_ratio = pixelRatio; + linesdfShader->u_ratio = data.pixelRatio; linesdfShader->u_blur = blur; linesdfShader->u_color = color; @@ -80,7 +81,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const linesdfShader->u_patternscale_b = {{ scaleXB, scaleYB }}; linesdfShader->u_tex_y_b = posB.y; linesdfShader->u_image = 0; - linesdfShader->u_sdfgamma = lineAtlas->width / (properties.dash_line_width * std::min(posA.width, posB.width) * 256.0 * pixelRatio) / 2; + linesdfShader->u_sdfgamma = lineAtlas->width / (properties.dash_line_width * std::min(posA.width, posB.width) * 256.0 * data.pixelRatio) / 2; linesdfShader->u_mix = properties.dash_array.t; bucket.drawLineSDF(*linesdfShader); @@ -96,7 +97,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const linepatternShader->u_matrix = vtxMatrix; linepatternShader->u_exmatrix = extrudeMatrix; linepatternShader->u_linewidth = {{ outset, inset }}; - linepatternShader->u_ratio = pixelRatio; + linepatternShader->u_ratio = data.pixelRatio; linepatternShader->u_blur = blur; linepatternShader->u_pattern_size_a = {{imagePosA.size[0] * factor * properties.image.fromScale, imagePosA.size[1]}}; @@ -120,7 +121,7 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const lineShader->u_matrix = vtxMatrix; lineShader->u_exmatrix = extrudeMatrix; lineShader->u_linewidth = {{ outset, inset }}; - lineShader->u_ratio = pixelRatio; + lineShader->u_ratio = data.pixelRatio; lineShader->u_blur = blur; lineShader->u_color = color; diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index d0757d629..6d12768e2 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -52,7 +53,7 @@ void Painter::renderSDF(SymbolBucket &bucket, sdfShader.u_zoom = (state.getNormalizedZoom() - zoomAdjust) * 10; // current zoom level - FadeProperties f = frameHistory.getFadeProperties(std::chrono::milliseconds(300)); + FadeProperties f = frameHistory.getFadeProperties(data.getDefaultFadeDuration()); sdfShader.u_fadedist = f.fadedist * 10; sdfShader.u_minfadezoom = std::floor(f.minfadezoom * 10); sdfShader.u_maxfadezoom = std::floor(f.maxfadezoom * 10); @@ -60,7 +61,7 @@ void Painter::renderSDF(SymbolBucket &bucket, // The default gamma value has to be adjust for the current pixelratio so that we're not // drawing blurry font on retina screens. - const float gamma = 0.105 * sdfFontSize / fontSize / pixelRatio; + const float gamma = 0.105 * sdfFontSize / fontSize / data.pixelRatio; const float sdfPx = 8.0f; const float blurOffset = 1.19f; diff --git a/src/mbgl/style/piecewisefunction_properties.hpp b/src/mbgl/style/piecewisefunction_properties.hpp index 0440655ba..f05ee6864 100644 --- a/src/mbgl/style/piecewisefunction_properties.hpp +++ b/src/mbgl/style/piecewisefunction_properties.hpp @@ -11,7 +11,6 @@ template struct PiecewiseConstantFunction { inline PiecewiseConstantFunction(const std::vector> &values_, std::chrono::duration duration_) : values(values_), duration(duration_) {} inline PiecewiseConstantFunction(T &value, std::chrono::duration duration_) : values({{ 0, value }}), duration(duration_) {} - inline PiecewiseConstantFunction() : values(), duration(std::chrono::milliseconds(300)) {} T evaluate(float z, const ZoomHistory &zoomHistory) const; private: diff --git a/src/mbgl/style/property_transition.hpp b/src/mbgl/style/property_transition.hpp index 584d67db5..4515fdc92 100644 --- a/src/mbgl/style/property_transition.hpp +++ b/src/mbgl/style/property_transition.hpp @@ -8,6 +8,8 @@ namespace mbgl { struct PropertyTransition { + explicit inline PropertyTransition(const Duration& duration_, const Duration& delay_) + : duration(duration_), delay(delay_) {} Duration duration = Duration::zero(); Duration delay = Duration::zero(); }; diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 415e34246..994592408 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -41,7 +42,7 @@ void Style::setJSON(const std::string& json, const std::string&) { return; } - StyleParser parser; + StyleParser parser(data); parser.parse(doc); sources = parser.getSources(); @@ -86,23 +87,25 @@ void Style::update(const TransformState& transform, } } -void Style::cascade(const std::vector& classes, const TimePoint& now) { +void Style::cascade() { for (const auto& layer : layers) { - layer->setClasses(classes, now, defaultTransition); + layer->setClasses(data.getClasses(), + data.getAnimationTime(), + PropertyTransition { data.getDefaultTransitionDuration(), data.getDefaultTransitionDelay() }); } } -void Style::recalculate(float z, const TimePoint& now) { +void Style::recalculate(float z) { uv::writelock lock(mtx); for (const auto& source : sources) { source->enabled = false; } - zoomHistory.update(z, now); + zoomHistory.update(z, data.getAnimationTime()); for (const auto& layer : layers) { - layer->updateProperties(z, now, zoomHistory); + layer->updateProperties(z, data.getAnimationTime(), zoomHistory); if (!layer->bucket) { continue; } @@ -124,10 +127,6 @@ Source* Style::getSource(const std::string& id) const { return it != sources.end() ? it->get() : nullptr; } -void Style::setDefaultTransitionDuration(Duration duration) { - defaultTransition.duration = duration; -} - bool Style::hasTransitions() const { for (const auto& layer : layers) { if (layer->hasTransitions()) { diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 16e0afcd4..6d8a7ae52 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -54,10 +54,9 @@ public: // a tile is ready so observers can render the tile. void update(const TransformState&, TexturePool&); - void cascade(const std::vector&, const TimePoint& now); - void recalculate(float z, const TimePoint& now); + void cascade(); + void recalculate(float z); - void setDefaultTransitionDuration(Duration); bool hasTransitions() const; std::exception_ptr getLastError() const { @@ -101,7 +100,6 @@ private: std::exception_ptr lastError; - PropertyTransition defaultTransition; std::unique_ptr mtx; ZoomHistory zoomHistory; diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp index 53313a548..4767bdafa 100644 --- a/src/mbgl/style/style_parser.cpp +++ b/src/mbgl/style/style_parser.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,8 @@ namespace mbgl { using JSVal = const rapidjson::Value&; -StyleParser::StyleParser() { +StyleParser::StyleParser(MapData& data_) + : data(data_) { } void StyleParser::parse(JSVal document) { @@ -399,13 +401,13 @@ template StyleParser::Result> StyleParser::parsePiecewiseConstantFunction(JSVal value, Duration duration) { if (!value.HasMember("stops")) { Log::Warning(Event::ParseStyle, "function must specify a function type"); - return Result> { StyleParserFailure, {} }; + return Result> { StyleParserFailure, { {}, duration } }; } auto stops = parseStops(value["stops"], ""); if (!std::get<0>(stops)) { - return Result> { StyleParserFailure, {} }; + return Result> { StyleParserFailure, { {}, duration } }; } return Result> { StyleParserSuccess, { std::get<1>(stops), duration } }; @@ -578,20 +580,21 @@ template<> StyleParser::Result StyleParser::parseProperty } template<> StyleParser::Result StyleParser::parseProperty(JSVal value, const char */*property_name*/) { - PropertyTransition transition; + PropertyTransition transition { data.getDefaultTransitionDuration(), data.getDefaultTransitionDelay() }; if (value.IsObject()) { + bool parsed = false; if (value.HasMember("duration") && value["duration"].IsNumber()) { transition.duration = std::chrono::milliseconds(value["duration"].GetUint()); + parsed = true; } if (value.HasMember("delay") && value["delay"].IsNumber()) { transition.delay = std::chrono::milliseconds(value["delay"].GetUint()); + parsed = true; + } + if (!parsed) { + return Result { StyleParserFailure, std::move(transition) }; } } - - if (transition.duration == Duration::zero() && transition.delay == Duration::zero()) { - return Result { StyleParserFailure, std::move(transition) }; - } - return Result { StyleParserSuccess, std::move(transition) }; } @@ -653,7 +656,7 @@ template<> StyleParser::Result> StyleParser::parseProperty(JSVal } template<> StyleParser::Result>>> StyleParser::parseProperty(JSVal value, const char *property_name, JSVal transition) { - Duration duration = std::chrono::milliseconds(300); + Duration duration = data.getDefaultFadeDuration(); if (transition.HasMember("duration")) { duration = std::chrono::milliseconds(transition["duration"].GetUint()); } @@ -667,13 +670,12 @@ template<> StyleParser::Result>>> { std::get<0>(floatarray), { parsed, duration } }; } else { Log::Warning(Event::ParseStyle, "value of '%s' must be an array of numbers, or a number array function", property_name); - return Result>>> { StyleParserFailure, {} }; + return Result>>> { StyleParserFailure, { {}, duration } }; } } template<> StyleParser::Result>> StyleParser::parseProperty(JSVal value, const char *property_name, JSVal transition) { - - Duration duration = std::chrono::milliseconds(300); + Duration duration = data.getDefaultFadeDuration(); if (transition.HasMember("duration")) { duration = std::chrono::milliseconds(transition["duration"].GetUint()); } @@ -686,7 +688,7 @@ template<> StyleParser::Result>> St return Result>> { StyleParserSuccess, { parsed, duration } }; } else { Log::Warning(Event::ParseStyle, "value of '%s' must be string or a string function", property_name); - return Result>> { StyleParserFailure, {} }; + return Result>> { StyleParserFailure, { {}, duration } }; } } diff --git a/src/mbgl/style/style_parser.hpp b/src/mbgl/style/style_parser.hpp index 2daa5e14d..5f0c509eb 100644 --- a/src/mbgl/style/style_parser.hpp +++ b/src/mbgl/style/style_parser.hpp @@ -31,7 +31,7 @@ public: template using Result = std::pair; - StyleParser(); + StyleParser(MapData& data); void parse(JSVal document); @@ -117,6 +117,9 @@ private: // URL template for glyph PBFs. std::string glyph_url; + + // Obtain default transition duration from map data. + MapData& data; }; } diff --git a/test/miscellaneous/style_parser.cpp b/test/miscellaneous/style_parser.cpp index 7a38ba054..e88d79841 100644 --- a/test/miscellaneous/style_parser.cpp +++ b/test/miscellaneous/style_parser.cpp @@ -3,6 +3,9 @@ #include #include +#include +#include + #include #include "../fixtures/fixture_log_observer.hpp" @@ -35,7 +38,11 @@ TEST_P(StyleParserTest, ParseStyle) { FixtureLogObserver* observer = new FixtureLogObserver(); Log::setObserver(std::unique_ptr(observer)); - StyleParser parser; + MapMode mapMode = MapMode::Continuous; + const float pixelRatio = 1.0f; + + MapData data(mapMode, pixelRatio); + StyleParser parser(data); parser.parse(styleDoc); for (auto it = infoDoc.MemberBegin(), end = infoDoc.MemberEnd(); it != end; it++) {