diff options
author | Tim Watson <tewatson89@gmail.com> | 2019-04-03 14:51:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-03 14:51:13 -0700 |
commit | 0ff25060dae4858a1b60e2277dbd8921de7a6785 (patch) | |
tree | d29d578b9b9d6cfb0999b7a30819d379b85172b7 /src | |
parent | ba2b7a74c420856401d344ff15b27771175c9819 (diff) | |
parent | 0f416fbbde9b146eb28a4bf88586738d12505007 (diff) | |
download | qtlocation-mapboxgl-0ff25060dae4858a1b60e2277dbd8921de7a6785.tar.gz |
Merge pull request #1 from mapbox/masterupstream/friedbunny-external-pr-14135
Merge Master
Diffstat (limited to 'src')
154 files changed, 3391 insertions, 1809 deletions
diff --git a/src/core-files.json b/src/core-files.json index 272faaf9b6..b257666e3e 100644 --- a/src/core-files.json +++ b/src/core-files.json @@ -82,7 +82,6 @@ "src/mbgl/programs/gl/line_gradient.cpp", "src/mbgl/programs/gl/line_pattern.cpp", "src/mbgl/programs/gl/line_sdf.cpp", - "src/mbgl/programs/gl/preludes.cpp", "src/mbgl/programs/gl/raster.cpp", "src/mbgl/programs/gl/shader_source.cpp", "src/mbgl/programs/gl/shaders.cpp", @@ -144,8 +143,10 @@ "src/mbgl/sprite/sprite_loader.cpp", "src/mbgl/sprite/sprite_loader_worker.cpp", "src/mbgl/sprite/sprite_parser.cpp", + "src/mbgl/storage/file_source.cpp", "src/mbgl/storage/network_status.cpp", "src/mbgl/storage/resource.cpp", + "src/mbgl/storage/resource_options.cpp", "src/mbgl/storage/resource_transform.cpp", "src/mbgl/storage/response.cpp", "src/mbgl/style/conversion/color_ramp_property_value.cpp", @@ -359,6 +360,7 @@ "mbgl/storage/offline.hpp": "include/mbgl/storage/offline.hpp", "mbgl/storage/online_file_source.hpp": "include/mbgl/storage/online_file_source.hpp", "mbgl/storage/resource.hpp": "include/mbgl/storage/resource.hpp", + "mbgl/storage/resource_options.hpp": "include/mbgl/storage/resource_options.hpp", "mbgl/storage/resource_transform.hpp": "include/mbgl/storage/resource_transform.hpp", "mbgl/storage/response.hpp": "include/mbgl/storage/response.hpp", "mbgl/style/color_ramp_property_value.hpp": "include/mbgl/style/color_ramp_property_value.hpp", @@ -613,6 +615,7 @@ "mbgl/renderer/group_by_layout.hpp": "src/mbgl/renderer/group_by_layout.hpp", "mbgl/renderer/image_atlas.hpp": "src/mbgl/renderer/image_atlas.hpp", "mbgl/renderer/image_manager.hpp": "src/mbgl/renderer/image_manager.hpp", + "mbgl/renderer/image_manager_observer.hpp": "src/mbgl/renderer/image_manager_observer.hpp", "mbgl/renderer/layers/render_background_layer.hpp": "src/mbgl/renderer/layers/render_background_layer.hpp", "mbgl/renderer/layers/render_circle_layer.hpp": "src/mbgl/renderer/layers/render_circle_layer.hpp", "mbgl/renderer/layers/render_custom_layer.hpp": "src/mbgl/renderer/layers/render_custom_layer.hpp", @@ -744,6 +747,7 @@ "mbgl/util/i18n.hpp": "src/mbgl/util/i18n.hpp", "mbgl/util/intersection_tests.hpp": "src/mbgl/util/intersection_tests.hpp", "mbgl/util/io.hpp": "src/mbgl/util/io.hpp", + "mbgl/util/literal.hpp": "src/mbgl/util/literal.hpp", "mbgl/util/longest_common_subsequence.hpp": "src/mbgl/util/longest_common_subsequence.hpp", "mbgl/util/mapbox.hpp": "src/mbgl/util/mapbox.hpp", "mbgl/util/mat2.hpp": "src/mbgl/util/mat2.hpp", diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index ab22404c15..345171b96e 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -10,7 +10,6 @@ #include <mbgl/style/layers/symbol_layer.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> #include <mbgl/style/expression/dsl.hpp> -#include <mbgl/storage/file_source.hpp> #include <boost/function_output_iterator.hpp> diff --git a/src/mbgl/gfx/attribute.hpp b/src/mbgl/gfx/attribute.hpp index 4f44d68d7b..f5188ccfdb 100644 --- a/src/mbgl/gfx/attribute.hpp +++ b/src/mbgl/gfx/attribute.hpp @@ -14,7 +14,7 @@ #define MBGL_DEFINE_ATTRIBUTE(type_, n_, name_) \ struct name_ { \ using Type = ::mbgl::gfx::AttributeType<type_, n_>; \ - static auto name() { \ + static constexpr auto name() { \ return #name_; \ } \ } diff --git a/src/mbgl/gfx/context.hpp b/src/mbgl/gfx/context.hpp index 90b62c94a4..e898006ff5 100644 --- a/src/mbgl/gfx/context.hpp +++ b/src/mbgl/gfx/context.hpp @@ -17,10 +17,14 @@ namespace gfx { class Context { protected: - Context(ContextType type_) : backend(type_) { + Context(ContextType type_, uint32_t maximumVertexBindingCount_) + : backend(type_), maximumVertexBindingCount(maximumVertexBindingCount_) { } +public: const ContextType backend; + static constexpr const uint32_t minimumRequiredVertexBindingCount = 8; + const uint32_t maximumVertexBindingCount; public: Context(Context&&) = delete; @@ -30,6 +34,10 @@ public: virtual ~Context() = default; public: + // Called at the end of a frame. + virtual void performCleanup() = 0; + +public: template <class Vertex> VertexBuffer<Vertex> createVertexBuffer(VertexVector<Vertex>&& v, @@ -92,11 +100,25 @@ public: texture.size = image.size; } + template <typename Image> + void updateTextureSub(Texture& texture, + const Image& image, + const uint16_t offsetX, + const uint16_t offsetY, + TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { + assert(image.size.width + offsetX <= texture.size.width); + assert(image.size.height + offsetY <= texture.size.height); + auto format = image.channels == 4 ? TexturePixelType::RGBA : TexturePixelType::Alpha; + updateTextureResourceSub(*texture.resource, offsetX, offsetY, image.size, image.data.get(), format, type); + } + protected: virtual std::unique_ptr<TextureResource> createTextureResource( Size, const void* data, TexturePixelType, TextureChannelDataType) = 0; virtual void updateTextureResource(const TextureResource&, Size, const void* data, TexturePixelType, TextureChannelDataType) = 0; + virtual void updateTextureResourceSub(const TextureResource&, uint16_t xOffset, uint16_t yOffset, Size, const void* data, + TexturePixelType, TextureChannelDataType) = 0; public: DrawScope createDrawScope() { diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index c4fe8b993f..c7f9ba3fd4 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -3,6 +3,7 @@ #include <mbgl/gfx/attribute.hpp> #include <mbgl/gl/types.hpp> #include <mbgl/util/ignore.hpp> +#include <mbgl/util/literal.hpp> #include <mbgl/util/indexed_tuple.hpp> #include <mbgl/util/optional.hpp> @@ -50,13 +51,15 @@ public: } }; - return Locations{ maybeBindLocation(As::name())... }; + return Locations{ maybeBindLocation( + concat_literals<&string_literal<'a', '_'>::value, &As::name>::value())... }; }()) { } template <class BinaryProgram> AttributeLocations(const BinaryProgram& program) - : locations{ program.attributeLocation(As::name())... } { + : locations{ program.attributeLocation( + concat_literals<&string_literal<'a', '_'>::value, &As::name>::value())... } { } NamedAttributeLocations getNamedLocations() const { @@ -68,7 +71,9 @@ public: } }; - util::ignore({ (maybeAddLocation(As::name(), locations.template get<As>()), 0)... }); + util::ignore({ (maybeAddLocation(concat_literals<&string_literal<'a', '_'>::value, &As::name>::value(), + locations.template get<As>()), + 0)... }); return result; } @@ -90,5 +95,36 @@ public: } }; +template <class> +class AttributeKey; + +constexpr auto attributeDefinePrefix() { + return "#define HAS_UNIFORM_u_"; +} + +template <class... As> +class AttributeKey<TypeList<As...>> final { +public: + static_assert(sizeof...(As) <= 32, "attribute count exceeds 32"); + + static uint32_t compute(const gfx::AttributeBindings<TypeList<As...>>& bindings) { + uint32_t value = 0; + util::ignore( + { (bindings.template get<As>() ? (void)(value |= 1 << TypeIndex<As, As...>::value) + : (void)0, + 0)... }); + return value; + } + + static std::string defines(const gfx::AttributeBindings<TypeList<As...>>& bindings) { + std::string result; + util::ignore({ (!bindings.template get<As>() + ? (void)(result += concat_literals<&attributeDefinePrefix, &As::name, &string_literal<'\n'>::value>::value()) + : (void)0, + 0)... }); + return result; + } +}; + } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 5193381251..6cee364379 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -5,6 +5,7 @@ #include <mbgl/gl/texture_resource.hpp> #include <mbgl/gl/draw_scope_resource.hpp> #include <mbgl/gl/texture.hpp> +#include <mbgl/gl/debugging.hpp> #include <mbgl/gl/debugging_extension.hpp> #include <mbgl/gl/vertex_array_extension.hpp> #include <mbgl/gl/program_binary_extension.hpp> @@ -67,7 +68,7 @@ static_assert(underlying_type(UniformDataType::SamplerCube) == GL_SAMPLER_CUBE, static_assert(std::is_same<BinaryProgramFormat, GLenum>::value, "OpenGL type mismatch"); Context::Context() - : gfx::Context(gfx::ContextType::OpenGL), maximumVertexBindingCount([] { + : gfx::Context(gfx::ContextType::OpenGL, [] { GLint value; MBGL_CHECK_ERROR(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value)); return value; @@ -160,12 +161,10 @@ void Context::enableDebugging() { MBGL_CHECK_ERROR(debugging->debugMessageCallback(extension::Debugging::DebugCallback, nullptr)); } -UniqueShader Context::createShader(ShaderType type, const std::string& source) { +UniqueShader Context::createShader(ShaderType type, const std::initializer_list<const char*>& sources) { UniqueShader result { MBGL_CHECK_ERROR(glCreateShader(static_cast<GLenum>(type))), { this } }; - const GLchar* sources = source.data(); - const auto lengths = static_cast<GLsizei>(source.length()); - MBGL_CHECK_ERROR(glShaderSource(result, 1, &sources, &lengths)); + MBGL_CHECK_ERROR(glShaderSource(result, static_cast<GLsizei>(sources.size()), sources.begin(), nullptr)); MBGL_CHECK_ERROR(glCompileShader(result)); GLint status = 0; @@ -547,6 +546,24 @@ void Context::updateTextureResource(const gfx::TextureResource& resource, Enum<gfx::TextureChannelDataType>::to(type), data)); } +void Context::updateTextureResourceSub(const gfx::TextureResource& resource, + const uint16_t xOffset, + const uint16_t yOffset, + const Size size, + const void* data, + gfx::TexturePixelType format, + gfx::TextureChannelDataType type) { + // Always use texture unit 0 for manipulating it. + activeTextureUnit = 0; + texture[0] = static_cast<const gl::TextureResource&>(resource).texture; + MBGL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, + xOffset, yOffset, + size.width, size.height, + Enum<gfx::TexturePixelType>::to(format), + Enum<gfx::TextureChannelDataType>::to(type), data)); +} + + std::unique_ptr<gfx::DrawScopeResource> Context::createDrawScopeResource() { return std::make_unique<gl::DrawScopeResource>(createVertexArray()); } @@ -708,6 +725,19 @@ void Context::draw(const gfx::DrawMode& drawMode, } void Context::performCleanup() { + // TODO: Find a better way to unbind VAOs after we're done with them without introducing + // unnecessary bind(0)/bind(N) sequences. + { + MBGL_DEBUG_GROUP(*this, "cleanup"); + + activeTextureUnit = 1; + texture[1] = 0; + activeTextureUnit = 0; + texture[0] = 0; + + bindVertexArray = 0; + } + for (auto id : abandonedPrograms) { if (program == id) { program.setDirty(); @@ -775,5 +805,9 @@ void Context::performCleanup() { } } +void Context::flush() { + MBGL_CHECK_ERROR(glFinish()); +} + } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index fe09390cc6..d46727cb7a 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -46,7 +46,7 @@ public: void enableDebugging(); - UniqueShader createShader(ShaderType type, const std::string& source); + UniqueShader createShader(ShaderType type, const std::initializer_list<const char*>& sources); UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader); UniqueProgram createProgram(BinaryProgramFormat binaryFormat, const std::string& binaryProgram); void verifyProgramLinkage(ProgramID); @@ -56,7 +56,7 @@ public: #if MBGL_HAS_BINARY_PROGRAMS bool supportsProgramBinaries() const; #else - constexpr bool supportsProgramBinaries() const { return false; } + constexpr static bool supportsProgramBinaries() { return false; } #endif optional<std::pair<BinaryProgramFormat, std::string>> getBinaryProgram(ProgramID) const; @@ -110,12 +110,17 @@ public: // Actually remove the objects we marked as abandoned with the above methods. // Only call this while the OpenGL context is exclusive to this thread. - void performCleanup(); + void performCleanup() override; // Drain pools and remove abandoned objects, in preparation for destroying the store. // Only call this while the OpenGL context is exclusive to this thread. void reset(); + // Flush pending graphics commands. Will block until the pipeline + // is empty. Should be used only with a very good reason because + // it will have a performance impact. + void flush(); + bool empty() const { return pooledTextures.empty() && abandonedPrograms.empty() @@ -172,9 +177,7 @@ public: #endif // MBGL_USE_GLES2 bool supportsHalfFloatTextures = false; - const uint32_t maximumVertexBindingCount; - static constexpr const uint32_t minimumRequiredVertexBindingCount = 8; - + private: State<value::StencilFunc> stencilFunc; State<value::StencilMask> stencilMask; @@ -208,6 +211,7 @@ private: std::unique_ptr<gfx::TextureResource> createTextureResource(Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; void updateTextureResource(const gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + void updateTextureResourceSub(const gfx::TextureResource&, const uint16_t xOffset, const uint16_t yOffset, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; std::unique_ptr<gfx::DrawScopeResource> createDrawScopeResource() override; diff --git a/src/mbgl/gl/debugging.cpp b/src/mbgl/gl/debugging.cpp index 7b8121f003..54cee5fc09 100644 --- a/src/mbgl/gl/debugging.cpp +++ b/src/mbgl/gl/debugging.cpp @@ -9,8 +9,8 @@ using namespace platform; #ifndef NDEBUG -DebugGroup::DebugGroup(const Context& context_, const std::string& name) : context(context_) { - if (auto debugging = context.getDebuggingExtension()) { +DebugGroup::DebugGroup(const gfx::Context& context_, const std::string& name) : context(context_) { + if (auto debugging = reinterpret_cast<const gl::Context&>(context).getDebuggingExtension()) { if (debugging->pushDebugGroup) { MBGL_CHECK_ERROR(debugging->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, GLsizei(name.size()), name.c_str())); } else if (debugging->pushGroupMarkerEXT) { @@ -20,7 +20,7 @@ DebugGroup::DebugGroup(const Context& context_, const std::string& name) : conte } DebugGroup::~DebugGroup() { - if (auto debugging = context.getDebuggingExtension()) { + if (auto debugging = reinterpret_cast<const gl::Context&>(context).getDebuggingExtension()) { if (debugging->popDebugGroup) { MBGL_CHECK_ERROR(debugging->popDebugGroup()); } else if (debugging->popGroupMarkerEXT) { diff --git a/src/mbgl/gl/debugging.hpp b/src/mbgl/gl/debugging.hpp index d24b727295..d85eb631be 100644 --- a/src/mbgl/gl/debugging.hpp +++ b/src/mbgl/gl/debugging.hpp @@ -5,19 +5,22 @@ #include <string> namespace mbgl { -namespace gl { +namespace gfx { class Context; +} // namespace gfx + +namespace gl { #ifndef NDEBUG class DebugGroup : private util::noncopyable { public: - DebugGroup(const Context&, const std::string&); + DebugGroup(const gfx::Context&, const std::string&); ~DebugGroup(); private: - const Context& context; + const gfx::Context& context; }; #define __MBGL_DEBUG_GROUP_NAME2(counter) __MBGL_DEBUG_GROUP_##counter diff --git a/src/mbgl/gl/features.hpp b/src/mbgl/gl/features.hpp index 1757093967..1da1371e45 100644 --- a/src/mbgl/gl/features.hpp +++ b/src/mbgl/gl/features.hpp @@ -3,5 +3,6 @@ #if __APPLE__ #define MBGL_HAS_BINARY_PROGRAMS 0 #else - #define MBGL_HAS_BINARY_PROGRAMS 1 + // https://github.com/mapbox/mapbox-gl-native/issues/14294 + #define MBGL_HAS_BINARY_PROGRAMS 0 #endif diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp index 9028ffdf53..1cec7671a1 100644 --- a/src/mbgl/gl/program.hpp +++ b/src/mbgl/gl/program.hpp @@ -18,6 +18,7 @@ #include <mbgl/util/logging.hpp> #include <mbgl/programs/program_parameters.hpp> +#include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/programs/gl/shaders.hpp> #include <string> @@ -31,93 +32,128 @@ public: using AttributeList = typename Name::AttributeList; using UniformList = typename Name::UniformList; using TextureList = typename Name::TextureList; - - Program(Context& context, const std::string& vertexSource, const std::string& fragmentSource) - : program( - context.createProgram(context.createShader(ShaderType::Vertex, vertexSource), - context.createShader(ShaderType::Fragment, fragmentSource))), - attributeLocations(context, program) { - // Re-link program after manually binding only active attributes in Attributes::queryLocations - context.linkProgram(program); - - // We have to re-initialize the uniforms state from the bindings as the uniform locations - // get shifted on some implementations - uniformStates.queryLocations(program); - - // Texture units are specified via uniforms as well, so we need query their locations - textureStates.queryLocations(program); - } - template <class BinaryProgram> - Program(Context& context, const BinaryProgram& binaryProgram) - : program(context.createProgram(binaryProgram.format(), binaryProgram.code())), - attributeLocations(binaryProgram) { - uniformStates.loadNamedLocations(binaryProgram); - textureStates.loadNamedLocations(binaryProgram); + Program(ProgramParameters programParameters_) + : programParameters(std::move(programParameters_)) { } - static std::unique_ptr<Program> createProgram(gl::Context& context, - const ProgramParameters& programParameters, - const char* name, - const char* vertexSource_, - const char* fragmentSource_) { - const std::string vertexSource = programs::gl::vertexSource(programParameters, vertexSource_); - const std::string fragmentSource = programs::gl::fragmentSource(programParameters, fragmentSource_); + const ProgramParameters programParameters; + + static constexpr const auto vertexOffset = programs::gl::ShaderSource<Name>::vertexOffset; + static constexpr const auto fragmentOffset = programs::gl::ShaderSource<Name>::fragmentOffset; + + class Instance { + public: + Instance(Context& context, + const std::initializer_list<const char*>& vertexSource, + const std::initializer_list<const char*>& fragmentSource) + : program(context.createProgram( + context.createShader(ShaderType::Vertex, vertexSource), + context.createShader(ShaderType::Fragment, fragmentSource))), + attributeLocations(context, program) { + // Re-link program after manually binding only active attributes in Attributes::queryLocations + context.linkProgram(program); + + // We have to re-initialize the uniforms state from the bindings as the uniform locations + // get shifted on some implementations + uniformStates.queryLocations(program); + + // Texture units are specified via uniforms as well, so we need query their locations + textureStates.queryLocations(program); + } + + template <class BinaryProgram> + Instance(Context& context, const BinaryProgram& binaryProgram) + : program(context.createProgram(binaryProgram.format(), binaryProgram.code())), + attributeLocations(binaryProgram) { + uniformStates.loadNamedLocations(binaryProgram); + textureStates.loadNamedLocations(binaryProgram); + } + + static std::unique_ptr<Instance> + createInstance(gl::Context& context, + const ProgramParameters& programParameters, + const std::string& additionalDefines) { + + #if MBGL_HAS_BINARY_PROGRAMS - optional<std::string> cachePath = programParameters.cachePath(name); - if (cachePath && context.supportsProgramBinaries()) { - const std::string identifier = programs::gl::programIdentifier(vertexSource, fragmentSource); - - try { - if (auto cachedBinaryProgram = util::readFile(*cachePath)) { - const BinaryProgram binaryProgram(std::move(*cachedBinaryProgram)); - if (binaryProgram.identifier() == identifier) { - return std::make_unique<Program>(context, binaryProgram); - } else { - Log::Warning(Event::OpenGL, - "Cached program %s changed. Recompilation required.", - name); + optional<std::string> cachePath = + programParameters.cachePath(programs::gl::ShaderSource<Name>::name); + std::string programIdentifier; + if (cachePath && context.supportsProgramBinaries()) { + programIdentifier = programs::gl::programIdentifier( + programParameters.getDefines(), additionalDefines, programs::gl::preludeHash, + programs::gl::ShaderSource<Name>::hash); + + try { + if (auto cachedBinaryProgram = util::readFile(*cachePath)) { + const BinaryProgram binaryProgram(std::move(*cachedBinaryProgram)); + if (binaryProgram.identifier() == programIdentifier) { + return std::make_unique<Instance>(context, binaryProgram); + } else { + Log::Warning(Event::OpenGL, + "Cached program %s changed. Recompilation required.", + programs::gl::ShaderSource<Name>::name); + } } + } catch (std::runtime_error& error) { + Log::Warning(Event::OpenGL, "Could not load cached program: %s", + error.what()); } - } catch (std::runtime_error& error) { - Log::Warning(Event::OpenGL, "Could not load cached program: %s", - error.what()); } +#endif // Compile the shader - auto result = std::make_unique<Program>(context, vertexSource, fragmentSource); + const std::initializer_list<const char*> vertexSource = { + programParameters.getDefines().c_str(), + additionalDefines.c_str(), + (programs::gl::shaderSource() + programs::gl::vertexPreludeOffset), + (programs::gl::shaderSource() + vertexOffset) + }; + const std::initializer_list<const char*> fragmentSource = { + programParameters.getDefines().c_str(), + additionalDefines.c_str(), + (programs::gl::shaderSource() + programs::gl::fragmentPreludeOffset), + (programs::gl::shaderSource() + fragmentOffset) + }; + auto result = std::make_unique<Instance>(context, vertexSource, fragmentSource); - try { - if (const auto binaryProgram = - result->template get<BinaryProgram>(context, identifier)) { - util::write_file(*cachePath, binaryProgram->serialize()); - Log::Warning(Event::OpenGL, "Caching program in: %s", (*cachePath).c_str()); +#if MBGL_HAS_BINARY_PROGRAMS + if (cachePath && context.supportsProgramBinaries()) { + try { + if (const auto binaryProgram = + result->template get<BinaryProgram>(context, programIdentifier)) { + util::write_file(*cachePath, binaryProgram->serialize()); + Log::Warning(Event::OpenGL, "Caching program in: %s", (*cachePath).c_str()); + } + } catch (std::runtime_error& error) { + Log::Warning(Event::OpenGL, "Failed to cache program: %s", error.what()); } - } catch (std::runtime_error& error) { - Log::Warning(Event::OpenGL, "Failed to cache program: %s", error.what()); } - +#endif + return std::move(result); } -#endif - (void)name; - return std::make_unique<Program>(context, vertexSource, fragmentSource); - } - - template <class BinaryProgram> - optional<BinaryProgram> get(Context& context, const std::string& identifier) const { - if (auto binaryProgram = context.getBinaryProgram(program)) { - return BinaryProgram{ binaryProgram->first, - std::move(binaryProgram->second), - identifier, - attributeLocations.getNamedLocations(), - uniformStates.getNamedLocations(), - textureStates.getNamedLocations() }; + template <class BinaryProgram> + optional<BinaryProgram> get(Context& context, const std::string& identifier) const { + if (auto binaryProgram = context.getBinaryProgram(program)) { + return BinaryProgram{ binaryProgram->first, + std::move(binaryProgram->second), + identifier, + attributeLocations.getNamedLocations(), + uniformStates.getNamedLocations(), + textureStates.getNamedLocations() }; + } + return {}; } - return {}; - } + + UniqueProgram program; + gl::AttributeLocations<AttributeList> attributeLocations; + gl::UniformStates<UniformList> uniformStates; + gl::TextureStates<TextureList> textureStates; + }; void draw(gfx::Context& genericContext, const gfx::DrawMode& drawMode, @@ -139,16 +175,29 @@ public: context.setColorMode(colorMode); context.setCullFaceMode(cullFaceMode); - context.program = program; + const uint32_t key = gl::AttributeKey<AttributeList>::compute(attributeBindings); + auto it = instances.find(key); + if (it == instances.end()) { + it = instances + .emplace(key, + Instance::createInstance( + context, + programParameters, + gl::AttributeKey<AttributeList>::defines(attributeBindings))) + .first; + } - uniformStates.bind(uniformValues); + auto& instance = *it->second; + context.program = instance.program; - textureStates.bind(context, textureBindings); + instance.uniformStates.bind(uniformValues); + + instance.textureStates.bind(context, textureBindings); auto& vertexArray = reinterpret_cast<gl::DrawScopeResource&>(*drawScope.resource).vertexArray; vertexArray.bind(context, indexBuffer, - attributeLocations.toBindingArray(attributeBindings)); + instance.attributeLocations.toBindingArray(attributeBindings)); context.draw(drawMode, indexOffset, @@ -156,11 +205,7 @@ public: } private: - UniqueProgram program; - - gl::AttributeLocations<AttributeList> attributeLocations; - gl::UniformStates<UniformList> uniformStates; - gl::TextureStates<TextureList> textureStates; + std::map<uint32_t, std::unique_ptr<Instance>> instances; }; } // namespace gl diff --git a/src/mbgl/gl/texture.hpp b/src/mbgl/gl/texture.hpp index 0569adc3b0..44b81f9a45 100644 --- a/src/mbgl/gl/texture.hpp +++ b/src/mbgl/gl/texture.hpp @@ -2,6 +2,7 @@ #include <mbgl/gfx/texture.hpp> #include <mbgl/gl/uniform.hpp> +#include <mbgl/util/literal.hpp> #include <mbgl/util/ignore.hpp> #include <vector> @@ -27,16 +28,19 @@ private: public: void queryLocations(const ProgramID& id) { - state = State{ gl::uniformLocation(id, Ts::name())... }; + state = State{ gl::uniformLocation(id, + concat_literals<&string_literal<'u', '_'>::value, &Ts::name>::value())... }; } template <class BinaryProgram> void loadNamedLocations(const BinaryProgram& program) { - state = State{ program.textureLocation(Ts::name())... }; + state = State{ program.textureLocation( + concat_literals<&string_literal<'u', '_'>::value, &Ts::name>::value())... }; } NamedUniformLocations getNamedLocations() const { - return NamedUniformLocations{ { Ts::name(), state.template get<Ts>().location }... }; + return NamedUniformLocations{ { concat_literals<&string_literal<'u', '_'>::value, &Ts::name>::value(), + state.template get<Ts>().location }... }; } void bind(gl::Context& context, const gfx::TextureBindings<TypeList<Ts...>>& bindings) { diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index 770f3e2294..89ef675a6b 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -3,6 +3,7 @@ #include <mbgl/gfx/uniform.hpp> #include <mbgl/gl/types.hpp> #include <mbgl/util/optional.hpp> +#include <mbgl/util/literal.hpp> #include <mbgl/util/ignore.hpp> #include <mbgl/util/indexed_tuple.hpp> @@ -73,21 +74,21 @@ public: util::ignore( { // Some shader programs have uniforms declared, but not used, so they're not active. // Therefore, we'll only verify them when they are indeed active. - (active.find(Us::name()) != active.end() - ? verifyUniform<typename Us::Value>(active.at(Us::name())) + (active.find(concat_literals<&string_literal<'u', '_'>::value, &Us::name>::value()) != active.end() + ? verifyUniform<typename Us::Value>(active.at(concat_literals<&string_literal<'u', '_'>::value, &Us::name>::value())) : false)... }); #endif - state = State{ gl::uniformLocation(id, Us::name())... }; + state = State{ gl::uniformLocation(id, concat_literals<&string_literal<'u', '_'>::value, &Us::name>::value())... }; } template <class BinaryProgram> void loadNamedLocations(const BinaryProgram& program) { - state = State{ UniformState<typename Us::Value>(program.uniformLocation(Us::name()))... }; + state = State{ UniformState<typename Us::Value>(program.uniformLocation(concat_literals<&string_literal<'u', '_'>::value, &Us::name>::value()))... }; } NamedUniformLocations getNamedLocations() const { - return NamedUniformLocations{ { Us::name(), state.template get<Us>().location }... }; + return NamedUniformLocations{ { concat_literals<&string_literal<'u', '_'>::value, &Us::name>::value(), state.template get<Us>().location }... }; } void bind(const gfx::UniformValues<TypeList<Us...>>& values) { diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index 139a42113c..0197df1066 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -5,13 +5,25 @@ namespace mbgl { using namespace style; +namespace { + +const Shaping& getAnyShaping(const ShapedTextOrientations& shapedTextOrientations) { + if (shapedTextOrientations.right) return shapedTextOrientations.right; + if (shapedTextOrientations.center) return shapedTextOrientations.center; + if (shapedTextOrientations.left) return shapedTextOrientations.left; + if (shapedTextOrientations.vertical) return shapedTextOrientations.vertical; + return shapedTextOrientations.horizontal; +} + +} // namespace + SymbolInstance::SymbolInstance(Anchor& anchor_, GeometryCoordinates line_, - const std::pair<Shaping, Shaping>& shapedTextOrientations, + const ShapedTextOrientations& shapedTextOrientations, optional<PositionedIcon> shapedIcon, const SymbolLayoutProperties::Evaluated& layout, const float layoutTextSize, - const float textBoxScale, + const float textBoxScale_, const float textPadding, const SymbolPlacementType textPlacement, const std::array<float, 2> textOffset_, @@ -24,43 +36,70 @@ SymbolInstance::SymbolInstance(Anchor& anchor_, const std::size_t dataFeatureIndex_, const std::u16string& key_, const float overscaling, - const float rotate) : + const float rotate, + float radialTextOffset_) : anchor(anchor_), line(line_), hasText(false), hasIcon(shapedIcon), // Create the collision features that will be used to check whether this symbol instance can be placed - textCollisionFeature(line_, anchor, shapedTextOrientations.first, textBoxScale, textPadding, textPlacement, indexedFeature, overscaling, rotate), + // As a collision approximation, we can use either the vertical or any of the horizontal versions of the feature + textCollisionFeature(line_, anchor, getAnyShaping(shapedTextOrientations), textBoxScale_, textPadding, textPlacement, indexedFeature, overscaling, rotate), iconCollisionFeature(line_, anchor, shapedIcon, iconBoxScale, iconPadding, indexedFeature, rotate), + writingModes(WritingModeType::None), layoutFeatureIndex(layoutFeatureIndex_), dataFeatureIndex(dataFeatureIndex_), textOffset(textOffset_), iconOffset(iconOffset_), - key(key_) { + key(key_), + textBoxScale(textBoxScale_), + radialTextOffset(radialTextOffset_), + singleLine(shapedTextOrientations.singleLine) { // Create the quads used for rendering the icon and glyphs. if (shapedIcon) { - iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.first); + iconQuad = getIconQuad(*shapedIcon, layout, layoutTextSize, shapedTextOrientations.horizontal); } - if (shapedTextOrientations.first) { - horizontalGlyphQuads = getGlyphQuads(shapedTextOrientations.first, layout, textPlacement, positions); + + bool singleLineInitialized = false; + const auto initHorizontalGlyphQuads = [&] (SymbolQuads& quads, const Shaping& shaping) { + writingModes |= WritingModeType::Horizontal; + if (!singleLine) { + quads = getGlyphQuads(shaping, textOffset, layout, textPlacement, positions); + return; + } + if (!singleLineInitialized) { + rightJustifiedGlyphQuads = getGlyphQuads(shaping, textOffset, layout, textPlacement, positions); + singleLineInitialized = true; + } + }; + + if (shapedTextOrientations.right) { + initHorizontalGlyphQuads(rightJustifiedGlyphQuads, shapedTextOrientations.right); } - if (shapedTextOrientations.second) { - verticalGlyphQuads = getGlyphQuads(shapedTextOrientations.second, layout, textPlacement, positions); + + if (shapedTextOrientations.center) { + initHorizontalGlyphQuads(centerJustifiedGlyphQuads, shapedTextOrientations.center); } - // 'hasText' depends on finding at least one glyph in the shaping that's also in the GlyphPositionMap - hasText = horizontalGlyphQuads.size() > 0 || verticalGlyphQuads.size() > 0; - if (shapedTextOrientations.first && shapedTextOrientations.second) { - writingModes = WritingModeType::Horizontal | WritingModeType::Vertical; - } else if (shapedTextOrientations.first) { - writingModes = WritingModeType::Horizontal; - } else if (shapedTextOrientations.second) { - writingModes = WritingModeType::Vertical; - } else { - writingModes = WritingModeType::None; + if (shapedTextOrientations.left) { + initHorizontalGlyphQuads(leftJustifiedGlyphQuads, shapedTextOrientations.left); } + + if (shapedTextOrientations.vertical) { + writingModes |= WritingModeType::Vertical; + verticalGlyphQuads = getGlyphQuads(shapedTextOrientations.vertical, textOffset, layout, textPlacement, positions); + } + + // 'hasText' depends on finding at least one glyph in the shaping that's also in the GlyphPositionMap + hasText = !rightJustifiedGlyphQuads.empty() || !centerJustifiedGlyphQuads.empty() || !leftJustifiedGlyphQuads.empty() || !verticalGlyphQuads.empty(); } +optional<size_t> SymbolInstance::getDefaultHorizontalPlacedTextIndex() const { + if (placedRightTextIndex) return placedRightTextIndex; + if (placedCenterTextIndex) return placedCenterTextIndex; + if (placedLeftTextIndex) return placedLeftTextIndex; + return nullopt; +} } // namespace mbgl diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index 6148d7fe88..5169b16adb 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -11,11 +11,21 @@ namespace mbgl { class Anchor; class IndexedSubfeature; +struct ShapedTextOrientations { + Shaping horizontal; + Shaping vertical; + // The following are used with variable text placement on. + Shaping& right = horizontal; + Shaping center; + Shaping left; + bool singleLine = false; +}; + class SymbolInstance { public: SymbolInstance(Anchor& anchor, GeometryCoordinates line, - const std::pair<Shaping, Shaping>& shapedTextOrientations, + const ShapedTextOrientations& shapedTextOrientations, optional<PositionedIcon> shapedIcon, const style::SymbolLayoutProperties::Evaluated&, const float layoutTextSize, @@ -32,14 +42,21 @@ public: const std::size_t dataFeatureIndex, const std::u16string& key, const float overscaling, - const float rotate); + const float rotate, + float radialTextOffset); + optional<size_t> getDefaultHorizontalPlacedTextIndex() const; Anchor anchor; GeometryCoordinates line; bool hasText; bool hasIcon; - SymbolQuads horizontalGlyphQuads; + // Note: When singleLine == true, only `rightJustifiedGlyphQuads` is populated. + SymbolQuads rightJustifiedGlyphQuads; + SymbolQuads centerJustifiedGlyphQuads; + SymbolQuads leftJustifiedGlyphQuads; + SymbolQuads verticalGlyphQuads; + optional<SymbolQuad> iconQuad; CollisionFeature textCollisionFeature; CollisionFeature iconCollisionFeature; @@ -50,9 +67,14 @@ public: std::array<float, 2> iconOffset; std::u16string key; bool isDuplicate; - optional<size_t> placedTextIndex; + optional<size_t> placedRightTextIndex; + optional<size_t> placedCenterTextIndex; + optional<size_t> placedLeftTextIndex; optional<size_t> placedVerticalTextIndex; optional<size_t> placedIconIndex; + float textBoxScale; + float radialTextOffset; + bool singleLine; uint32_t crossTileID = 0; }; diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index c40a705d7f..d1c50d7773 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -174,44 +174,173 @@ bool SymbolLayout::hasSymbolInstances() const { return !symbolInstances.empty(); } +namespace { + +// The radial offset is to the edge of the text box +// In the horizontal direction, the edge of the text box is where glyphs start +// But in the vertical direction, the glyphs appear to "start" at the baseline +// We don't actually load baseline data, but we assume an offset of ONE_EM - 17 +// (see "yOffset" in shaping.js) +const float baselineOffset = 7.0f; + +// We don't care which shaping we get because this is used for collision purposes +// and all the justifications have the same collision box. +const Shaping& getDefaultHorizontalShaping(const ShapedTextOrientations& shapedTextOrientations) { + if (shapedTextOrientations.right) return shapedTextOrientations.right; + if (shapedTextOrientations.center) return shapedTextOrientations.center; + if (shapedTextOrientations.left) return shapedTextOrientations.left; + return shapedTextOrientations.horizontal; +} + +Shaping& shapingForTextJustifyType(ShapedTextOrientations& shapedTextOrientations, style::TextJustifyType type) { + switch(type) { + case style::TextJustifyType::Right: return shapedTextOrientations.right; + case style::TextJustifyType::Left: return shapedTextOrientations.left; + case style::TextJustifyType::Center: return shapedTextOrientations.center; + default: + assert(false); + return shapedTextOrientations.horizontal; + } +} + +} // namespace + +// static +Point<float> SymbolLayout::evaluateRadialOffset(SymbolAnchorType anchor, float radialOffset) { + Point<float> result{}; + // solve for r where r^2 + r^2 = radialOffset^2 + const float sqrt2 = 1.41421356237f; + const float hypotenuse = radialOffset / sqrt2; + + switch (anchor) { + case SymbolAnchorType::TopRight: + case SymbolAnchorType::TopLeft: + result.y = hypotenuse - baselineOffset; + break; + case SymbolAnchorType::BottomRight: + case SymbolAnchorType::BottomLeft: + result.y = -hypotenuse + baselineOffset; + break; + case SymbolAnchorType::Bottom: + result.y = -radialOffset + baselineOffset; + break; + case SymbolAnchorType::Top: + result.y = radialOffset - baselineOffset; + break; + default: + break; + } + + switch (anchor) { + case SymbolAnchorType::TopRight: + case SymbolAnchorType::BottomRight: + result.x = -hypotenuse; + break; + case SymbolAnchorType::TopLeft: + case SymbolAnchorType::BottomLeft: + result.x = hypotenuse; + break; + case SymbolAnchorType::Left: + result.x = radialOffset; + break; + case SymbolAnchorType::Right: + result.x = -radialOffset; + break; + default: + break; + } + + return result; +} + void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions& glyphPositions, const ImageMap& imageMap, const ImagePositions& imagePositions) { - const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && - layout.get<SymbolPlacement>() != SymbolPlacementType::Point; + const bool isPointPlacement = layout.get<SymbolPlacement>() == SymbolPlacementType::Point; + const bool textAlongLine = layout.get<TextRotationAlignment>() == AlignmentType::Map && !isPointPlacement; for (auto it = features.begin(); it != features.end(); ++it) { auto& feature = *it; if (feature.geometry.empty()) continue; - std::pair<Shaping, Shaping> shapedTextOrientations; + ShapedTextOrientations shapedTextOrientations; optional<PositionedIcon> shapedIcon; + Point<float> textOffset; // if feature has text, shape the text if (feature.formattedText) { - auto applyShaping = [&] (const TaggedString& formattedText, WritingModeType writingMode) { - const float oneEm = 24.0f; + const float lineHeight = layout.get<TextLineHeight>() * util::ONE_EM; + const float spacing = util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) ? layout.evaluate<TextLetterSpacing>(zoom, feature) * util::ONE_EM : 0.0f; + + auto applyShaping = [&] (const TaggedString& formattedText, WritingModeType writingMode, SymbolAnchorType textAnchor, TextJustifyType textJustify) { const Shaping result = getShaping( /* string */ formattedText, - /* maxWidth: ems */ layout.get<SymbolPlacement>() == SymbolPlacementType::Point ? - layout.evaluate<TextMaxWidth>(zoom, feature) * oneEm : 0, - /* lineHeight: ems */ layout.get<TextLineHeight>() * oneEm, - /* anchor */ layout.evaluate<TextAnchor>(zoom, feature), - /* justify */ layout.evaluate<TextJustify>(zoom, feature), - /* spacing: ems */ util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) ? layout.evaluate<TextLetterSpacing>(zoom, feature) * oneEm : 0.0f, - /* translate */ Point<float>(layout.evaluate<TextOffset>(zoom, feature)[0] * oneEm, layout.evaluate<TextOffset>(zoom, feature)[1] * oneEm), - /* verticalHeight */ oneEm, + /* maxWidth: ems */ isPointPlacement ? layout.evaluate<TextMaxWidth>(zoom, feature) * util::ONE_EM : 0.0f, + /* ems */ lineHeight, + textAnchor, + textJustify, + /* ems */ spacing, + /* translate */ textOffset, /* writingMode */ writingMode, /* bidirectional algorithm object */ bidi, /* glyphs */ glyphMap); return result; }; + const std::vector<style::TextVariableAnchorType> variableTextAnchor = layout.evaluate<TextVariableAnchor>(zoom, feature); + const float radialOffset = layout.evaluate<TextRadialOffset>(zoom, feature); + const SymbolAnchorType textAnchor = layout.evaluate<TextAnchor>(zoom, feature); + if (variableTextAnchor.empty()) { + // Layers with variable anchors use the `text-radial-offset` property and the [x, y] offset vector + // is calculated at placement time instead of layout time + if (radialOffset > 0.0f) { + // The style spec says don't use `text-offset` and `text-radial-offset` together + // but doesn't actually specify what happens if you use both. We go with the radial offset. + textOffset = evaluateRadialOffset(textAnchor, radialOffset * util::ONE_EM); + } else { + textOffset = { layout.evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM, + layout.evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}; + } + } + TextJustifyType textJustify = textAlongLine ? TextJustifyType::Center : layout.evaluate<TextJustify>(zoom, feature); + // If this layer uses text-variable-anchor, generate shapings for all justification possibilities. + if (!textAlongLine && !variableTextAnchor.empty()) { + std::vector<TextJustifyType> justifications; + if (textJustify != TextJustifyType::Auto) { + justifications.push_back(textJustify); + } else { + for (auto anchor : variableTextAnchor) { + justifications.push_back(getAnchorJustification(anchor)); + } + } + for (TextJustifyType justification: justifications) { + Shaping& shapingForJustification = shapingForTextJustifyType(shapedTextOrientations, justification); + if (shapingForJustification) { + continue; + } + // If using text-variable-anchor for the layer, we use a center anchor for all shapings and apply + // the offsets for the anchor in the placement step. + Shaping shaping = applyShaping(*feature.formattedText, WritingModeType::Horizontal, SymbolAnchorType::Center, justification); + if (shaping) { + shapingForJustification = std::move(shaping); + if (shaping.lineCount == 1u) { + shapedTextOrientations.singleLine = true; + break; + } + } + } + } else { + if (textJustify == TextJustifyType::Auto) { + textJustify = getAnchorJustification(textAnchor); + } + Shaping shaping = applyShaping(*feature.formattedText, WritingModeType::Horizontal, textAnchor, textJustify); + if (shaping) { + shapedTextOrientations.horizontal = std::move(shaping); + } - shapedTextOrientations.first = applyShaping(*feature.formattedText, WritingModeType::Horizontal); - - if (util::i18n::allowsVerticalWritingMode(feature.formattedText->rawText()) && textAlongLine) { - feature.formattedText->verticalizePunctuation(); - shapedTextOrientations.second = applyShaping(*feature.formattedText, WritingModeType::Vertical); + if (util::i18n::allowsVerticalWritingMode(feature.formattedText->rawText()) && textAlongLine) { + feature.formattedText->verticalizePunctuation(); + shapedTextOrientations.vertical = applyShaping(*feature.formattedText, WritingModeType::Vertical, textAnchor, textJustify); + } } } @@ -236,8 +365,8 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions } // if either shapedText or icon position is present, add the feature - if (shapedTextOrientations.first || shapedIcon) { - addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, glyphPositions); + if (getDefaultHorizontalShaping(shapedTextOrientations) || shapedIcon) { + addFeature(std::distance(features.begin(), it), feature, shapedTextOrientations, shapedIcon, glyphPositions, textOffset); } feature.geometry.clear(); @@ -248,15 +377,17 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const SymbolFeature& feature, - const std::pair<Shaping, Shaping>& shapedTextOrientations, + const ShapedTextOrientations& shapedTextOrientations, optional<PositionedIcon> shapedIcon, - const GlyphPositions& glyphPositions) { + const GlyphPositions& glyphPositions, + Point<float> offset) { const float minScale = 0.5f; const float glyphSize = 24.0f; const float layoutTextSize = layout.evaluate<TextSize>(zoom + 1, feature); const float layoutIconSize = layout.evaluate<IconSize>(zoom + 1, feature); - const std::array<float, 2> textOffset = layout.evaluate<TextOffset>(zoom, feature); + const std::array<float, 2> textOffset = {{ offset.x, offset.y }}; + const std::array<float, 2> iconOffset = layout.evaluate<IconOffset>(zoom, feature); // To reduce the number of labels that jump around when zooming we need @@ -274,6 +405,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const float iconPadding = layout.get<IconPadding>() * tilePixelRatio; const float textMaxAngle = layout.get<TextMaxAngle>() * util::DEG2RAD; const float rotation = layout.evaluate<IconRotate>(zoom, feature); + const float radialTextOffset = layout.evaluate<TextRadialOffset>(zoom, feature) * util::ONE_EM; const SymbolPlacementType textPlacement = layout.get<TextRotationAlignment>() != AlignmentType::Map ? SymbolPlacementType::Point : layout.get<SymbolPlacement>(); @@ -296,7 +428,7 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, textBoxScale, textPadding, textPlacement, textOffset, iconBoxScale, iconPadding, iconOffset, glyphPositions, indexedFeature, layoutFeatureIndex, feature.index, - feature.formattedText ? feature.formattedText->rawText() : std::u16string(), overscaling, rotation); + feature.formattedText ? feature.formattedText->rawText() : std::u16string(), overscaling, rotation, radialTextOffset); } }; @@ -308,8 +440,8 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, Anchors anchors = getAnchors(line, symbolSpacing, textMaxAngle, - (shapedTextOrientations.second ?: shapedTextOrientations.first).left, - (shapedTextOrientations.second ?: shapedTextOrientations.first).right, + (shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).left, + (shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).right, (shapedIcon ? shapedIcon->left() : 0), (shapedIcon ? shapedIcon->right() : 0), glyphSize, @@ -329,8 +461,8 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, if (line.size() > 1) { optional<Anchor> anchor = getCenterAnchor(line, textMaxAngle, - (shapedTextOrientations.second ?: shapedTextOrientations.first).left, - (shapedTextOrientations.second ?: shapedTextOrientations.first).right, + (shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).left, + (shapedTextOrientations.vertical ?: getDefaultHorizontalShaping(shapedTextOrientations)).right, (shapedIcon ? shapedIcon->left() : 0), (shapedIcon ? shapedIcon->right() : 0), glyphSize, @@ -414,25 +546,41 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn const bool sortFeaturesByY = zOrderByViewport && (layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() || layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>()); - auto bucket = std::make_shared<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances)); + auto bucket = std::make_shared<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), tilePixelRatio); for (SymbolInstance &symbolInstance : bucket->symbolInstances) { - const bool hasText = symbolInstance.hasText; const bool hasIcon = symbolInstance.hasIcon; + const bool singleLine = symbolInstance.singleLine; const auto& feature = features.at(symbolInstance.layoutFeatureIndex); // Insert final placement into collision tree and add glyphs/icons to buffers if (hasText && feature.formattedText) { - std::size_t index = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedTextIndex, symbolInstance.horizontalGlyphQuads); - + optional<std::size_t> lastAddedSection; + if (singleLine) { + optional<std::size_t> placedTextIndex; + lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, placedTextIndex, symbolInstance.rightJustifiedGlyphQuads, lastAddedSection); + symbolInstance.placedRightTextIndex = placedTextIndex; + symbolInstance.placedCenterTextIndex = placedTextIndex; + symbolInstance.placedLeftTextIndex = placedTextIndex; + } else { + if (!symbolInstance.rightJustifiedGlyphQuads.empty()) { + lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedRightTextIndex, symbolInstance.rightJustifiedGlyphQuads, lastAddedSection); + } + if (!symbolInstance.centerJustifiedGlyphQuads.empty()) { + lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedCenterTextIndex, symbolInstance.centerJustifiedGlyphQuads, lastAddedSection); + } + if (!symbolInstance.leftJustifiedGlyphQuads.empty()) { + lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, symbolInstance.writingModes, symbolInstance.placedLeftTextIndex, symbolInstance.leftJustifiedGlyphQuads, lastAddedSection); + } + } if (symbolInstance.writingModes & WritingModeType::Vertical) { - index = addSymbolGlyphQuads(*bucket, symbolInstance, feature, WritingModeType::Vertical, symbolInstance.placedVerticalTextIndex, symbolInstance.verticalGlyphQuads, index); + lastAddedSection = addSymbolGlyphQuads(*bucket, symbolInstance, feature, WritingModeType::Vertical, symbolInstance.placedVerticalTextIndex, symbolInstance.verticalGlyphQuads, lastAddedSection); } - - updatePaintPropertiesForSection(*bucket, feature, index); + assert(lastAddedSection); // True, as hasText == true; + updatePaintPropertiesForSection(*bucket, feature, *lastAddedSection); } if (hasIcon) { @@ -600,7 +748,7 @@ void SymbolLayout::addToDebugBuffers(SymbolBucket& bucket) { // Dynamic vertices are initialized so that the vertex count always agrees with // the layout vertex buffer, but they will always be updated before rendering happens - auto dynamicVertex = CollisionBoxProgram::dynamicVertex(false, false); + auto dynamicVertex = CollisionBoxProgram::dynamicVertex(false, false, {}); collisionBuffer.dynamicVertices.emplace_back(dynamicVertex); collisionBuffer.dynamicVertices.emplace_back(dynamicVertex); collisionBuffer.dynamicVertices.emplace_back(dynamicVertex); diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 53c66d31fe..d88c79c552 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -46,12 +46,15 @@ public: const std::string bucketLeaderID; std::vector<SymbolInstance> symbolInstances; + static Point<float> evaluateRadialOffset(style::SymbolAnchorType anchor, float radialOffset); + private: void addFeature(const size_t, const SymbolFeature&, - const std::pair<Shaping, Shaping>& shapedTextOrientations, + const ShapedTextOrientations& shapedTextOrientations, optional<PositionedIcon> shapedIcon, - const GlyphPositions&); + const GlyphPositions&, + Point<float> textOffset); bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&); std::map<std::u16string, std::vector<Anchor>> compareText; diff --git a/src/mbgl/layout/symbol_projection.cpp b/src/mbgl/layout/symbol_projection.cpp index dff2a569ac..b7858f8deb 100644 --- a/src/mbgl/layout/symbol_projection.cpp +++ b/src/mbgl/layout/symbol_projection.cpp @@ -291,9 +291,9 @@ namespace mbgl { gfx::VertexVector<gfx::Vertex<SymbolDynamicLayoutAttributes>>& dynamicVertexArray, const Point<float>& projectedAnchorPoint, const float aspectRatio) { - const float fontScale = fontSize / 24.0; - const float lineOffsetX = symbol.lineOffset[0] * fontSize; - const float lineOffsetY = symbol.lineOffset[1] * fontSize; + const float fontScale = fontSize / util::ONE_EM; + const float lineOffsetX = symbol.lineOffset[0] * fontScale; + const float lineOffsetY = symbol.lineOffset[1] * fontScale; std::vector<PlacedGlyph> placedGlyphs; if (symbol.glyphOffsets.size() > 1) { diff --git a/src/mbgl/layout/symbol_projection.hpp b/src/mbgl/layout/symbol_projection.hpp index 03e660b474..3699eee290 100644 --- a/src/mbgl/layout/symbol_projection.hpp +++ b/src/mbgl/layout/symbol_projection.hpp @@ -60,4 +60,9 @@ namespace mbgl { const mat4& labelPlaneMatrix, const bool returnTileDistance); + void hideGlyphs(std::size_t numGlyphs, gfx::VertexVector<gfx::Vertex<SymbolDynamicLayoutAttributes>>& dynamicVertices); + void addDynamicAttributes(const Point<float>& anchorPoint, + const float angle, + gfx::VertexVector<gfx::Vertex<SymbolDynamicLayoutAttributes>>& dynamicVertices); + } // end namespace mbgl diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index f545fc8095..b22a9ee2f2 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -27,24 +27,16 @@ namespace mbgl { using namespace style; -Map::Map(RendererFrontend& rendererFrontend, - MapObserver& mapObserver, - const Size size, - const float pixelRatio, - FileSource& fileSource, +Map::Map(RendererFrontend& frontend, + MapObserver& observer, Scheduler& scheduler, - const MapOptions& options) - : impl(std::make_unique<Impl>(*this, - rendererFrontend, - mapObserver, - fileSource, - scheduler, - size, - pixelRatio, - options.mapMode(), - options.constrainMode(), - options.viewportMode(), - options.crossSourceCollisions())) {} + const MapOptions& mapOptions, + const ResourceOptions& resourceOptions) + : impl(std::make_unique<Impl>(frontend, observer, scheduler, + FileSource::getSharedFileSource(resourceOptions), + mapOptions)) {} + +Map::Map(std::unique_ptr<Impl> impl_) : impl(std::move(impl_)) {} Map::~Map() = default; @@ -139,9 +131,7 @@ CameraOptions Map::getCameraOptions(const EdgeInsets& padding) const { } void Map::jumpTo(const CameraOptions& camera) { - impl->cameraMutated = true; - impl->transform.jumpTo(camera); - impl->onUpdate(); + impl->jumpTo(camera); } void Map::easeTo(const CameraOptions& camera, const AnimationOptions& animation) { @@ -214,8 +204,13 @@ CameraOptions cameraForLatLngs(const std::vector<LatLng>& latLngs, const Transfo scaleY -= (padding.top() + padding.bottom()) / height; minScale = util::min(scaleX, scaleY); } - double zoom = transform.getZoom() + util::log2(minScale); - zoom = util::clamp(zoom, transform.getState().getMinZoom(), transform.getState().getMaxZoom()); + + double zoom = transform.getZoom(); + if (minScale > 0) { + zoom = util::clamp(zoom + util::log2(minScale), transform.getState().getMinZoom(), transform.getState().getMaxZoom()); + } else { + Log::Error(Event::General, "Unable to calculate appropriate zoom level for bounds. Vertical or horizontal padding is greater than map's height or width."); + } // Calculate the center point of a virtual bounds that is extended in all directions by padding. ScreenCoordinate centerPixel = nePixel + swPixel; @@ -312,48 +307,37 @@ BoundOptions Map::getBounds() const { .withMaxZoom(impl->transform.getState().getMaxZoom()); } -#pragma mark - Size +#pragma mark - Map options void Map::setSize(const Size size) { impl->transform.resize(size); impl->onUpdate(); } -Size Map::getSize() const { - return impl->transform.getState().getSize(); -} - -#pragma mark - North Orientation - void Map::setNorthOrientation(NorthOrientation orientation) { impl->transform.setNorthOrientation(orientation); impl->onUpdate(); } -NorthOrientation Map::getNorthOrientation() const { - return impl->transform.getNorthOrientation(); -} - -#pragma mark - Constrain mode - void Map::setConstrainMode(mbgl::ConstrainMode mode) { impl->transform.setConstrainMode(mode); impl->onUpdate(); } -ConstrainMode Map::getConstrainMode() const { - return impl->transform.getConstrainMode(); -} - -#pragma mark - Viewport mode - void Map::setViewportMode(mbgl::ViewportMode mode) { impl->transform.setViewportMode(mode); impl->onUpdate(); } -ViewportMode Map::getViewportMode() const { - return impl->transform.getViewportMode(); +MapOptions Map::getMapOptions() const { + return std::move(MapOptions() + .withMapMode(impl->mode) + .withConstrainMode(impl->transform.getConstrainMode()) + .withViewportMode(impl->transform.getViewportMode()) + .withCrossSourceCollisions(impl->crossSourceCollisions) + .withNorthOrientation(impl->transform.getNorthOrientation()) + .withSize(impl->transform.getState().getSize()) + .withPixelRatio(impl->pixelRatio)); } #pragma mark - Projection mode diff --git a/src/mbgl/map/map_impl.cpp b/src/mbgl/map/map_impl.cpp index 84cf324722..1ec7255822 100644 --- a/src/mbgl/map/map_impl.cpp +++ b/src/mbgl/map/map_impl.cpp @@ -1,39 +1,31 @@ #include <mbgl/layermanager/layer_manager.hpp> #include <mbgl/map/map_impl.hpp> #include <mbgl/renderer/update_parameters.hpp> +#include <mbgl/storage/file_source.hpp> #include <mbgl/style/style_impl.hpp> #include <mbgl/util/exception.hpp> namespace mbgl { -Map::Impl::Impl(Map& map_, - RendererFrontend& frontend, - MapObserver& mapObserver, - FileSource& fileSource_, +Map::Impl::Impl(RendererFrontend& frontend_, + MapObserver& observer_, Scheduler& scheduler_, - Size size_, - float pixelRatio_, - MapMode mode_, - ConstrainMode constrainMode_, - ViewportMode viewportMode_, - bool crossSourceCollisions_) - : map(map_), - observer(mapObserver), - rendererFrontend(frontend), - fileSource(fileSource_), - scheduler(scheduler_), - transform(observer, - constrainMode_, - viewportMode_), - mode(mode_), - pixelRatio(pixelRatio_), - crossSourceCollisions(crossSourceCollisions_), - style(std::make_unique<style::Style>(scheduler, fileSource, pixelRatio)), - annotationManager(*style) { - + std::shared_ptr<FileSource> fileSource_, + const MapOptions& mapOptions) + : observer(observer_), + rendererFrontend(frontend_), + scheduler(scheduler_), + transform(observer, mapOptions.constrainMode(), mapOptions.viewportMode()), + mode(mapOptions.mapMode()), + pixelRatio(mapOptions.pixelRatio()), + crossSourceCollisions(mapOptions.crossSourceCollisions()), + fileSource(std::move(fileSource_)), + style(std::make_unique<style::Style>(scheduler, *fileSource, pixelRatio)), + annotationManager(*style) { + transform.setNorthOrientation(mapOptions.northOrientation()); style->impl->setObserver(this); rendererFrontend.setObserver(*this); - transform.resize(size_); + transform.resize(mapOptions.size()); } Map::Impl::~Impl() { @@ -73,7 +65,7 @@ void Map::Impl::onUpdate() { style->impl->getSourceImpls(), style->impl->getLayerImpls(), annotationManager, - fileSource, + *fileSource, prefetchZoomDelta, bool(stillImageRequest), crossSourceCollisions @@ -90,7 +82,7 @@ void Map::Impl::onStyleLoading() { void Map::Impl::onStyleLoaded() { if (!cameraMutated) { - map.jumpTo(style->getDefaultCamera()); + jumpTo(style->getDefaultCamera()); } if (LayerManager::annotationsEnabled) { annotationManager.onStyleLoaded(); @@ -173,4 +165,20 @@ void Map::Impl::onDidFinishRenderingMap() { } }; +void Map::Impl::jumpTo(const CameraOptions& camera) { + cameraMutated = true; + transform.jumpTo(camera); + onUpdate(); +} + +void Map::Impl::onStyleImageMissing(const std::string& id, std::function<void()> done) { + + if (style->getImage(id) == nullptr) { + observer.onStyleImageMissing(id); + } + + done(); + onUpdate(); +} + } // namespace mbgl diff --git a/src/mbgl/map/map_impl.hpp b/src/mbgl/map/map_impl.hpp index 32dc728b70..f233f78275 100644 --- a/src/mbgl/map/map_impl.hpp +++ b/src/mbgl/map/map_impl.hpp @@ -1,14 +1,15 @@ #pragma once +#include <mbgl/actor/actor.hpp> #include <mbgl/actor/scheduler.hpp> #include <mbgl/annotation/annotation_manager.hpp> #include <mbgl/map/map.hpp> #include <mbgl/map/map_observer.hpp> +#include <mbgl/map/map_options.hpp> #include <mbgl/map/mode.hpp> #include <mbgl/map/transform.hpp> #include <mbgl/renderer/renderer_frontend.hpp> #include <mbgl/renderer/renderer_observer.hpp> -#include <mbgl/storage/file_source.hpp> #include <mbgl/style/observer.hpp> #include <mbgl/style/source.hpp> #include <mbgl/style/style.hpp> @@ -16,6 +17,9 @@ namespace mbgl { +class FileSource; +class ResourceTransform; + struct StillImageRequest { StillImageRequest(Map::StillImageCallback&& callback_) : callback(std::move(callback_)) { @@ -26,20 +30,7 @@ struct StillImageRequest { class Map::Impl : public style::Observer, public RendererObserver { public: - Impl(Map&, - RendererFrontend&, - MapObserver&, - FileSource&, - Scheduler&, - - Size size, - float pixelRatio, - - MapMode, - ConstrainMode, - ViewportMode, - bool crossSourceCollisions); - + Impl(RendererFrontend&, MapObserver&, Scheduler&, std::shared_ptr<FileSource>, const MapOptions&); ~Impl() final; // StyleObserver @@ -56,11 +47,13 @@ public: void onDidFinishRenderingFrame(RenderMode, bool) final; void onWillStartRenderingMap() final; void onDidFinishRenderingMap() final; + void onStyleImageMissing(const std::string&, std::function<void()>) final; + + // Map + void jumpTo(const CameraOptions&); - Map& map; MapObserver& observer; RendererFrontend& rendererFrontend; - FileSource& fileSource; Scheduler& scheduler; Transform transform; @@ -71,6 +64,8 @@ public: MapDebugOptions debugOptions { MapDebugOptions::NoDebug }; + std::shared_ptr<FileSource> fileSource; + std::unique_ptr<style::Style> style; AnnotationManager annotationManager; diff --git a/src/mbgl/map/map_options.cpp b/src/mbgl/map/map_options.cpp index 118fcaf3df..4cebb6adab 100644 --- a/src/mbgl/map/map_options.cpp +++ b/src/mbgl/map/map_options.cpp @@ -1,7 +1,4 @@ #include <mbgl/map/map_options.hpp> -#include <mbgl/util/constants.hpp> - -#include <cassert> namespace mbgl { @@ -10,14 +7,16 @@ public: MapMode mapMode = MapMode::Continuous; ConstrainMode constrainMode = ConstrainMode::HeightOnly; ViewportMode viewportMode = ViewportMode::Default; - std::string cachePath; - std::string assetRoot; - uint64_t maximumSize{mbgl::util::DEFAULT_MAX_CACHE_SIZE}; + NorthOrientation orientation = NorthOrientation::Upwards; bool crossSourceCollisions = true; + Size size = { 64, 64 }; + float pixelRatio = 1.0; }; -MapOptions::MapOptions() : impl_(std::make_shared<MapOptions::Impl>()) {} +// These requires the complete type of Impl. +MapOptions::MapOptions() : impl_(std::make_unique<Impl>()) {} MapOptions::~MapOptions() = default; +MapOptions::MapOptions(MapOptions&&) noexcept = default; MapOptions& MapOptions::withMapMode(MapMode mode) { impl_->mapMode = mode; @@ -46,40 +45,40 @@ ViewportMode MapOptions::viewportMode() const { return impl_->viewportMode; } -MapOptions& MapOptions::withCachePath(std::string path) { - impl_->cachePath = std::move(path); +MapOptions& MapOptions::withCrossSourceCollisions(bool enableCollisions) { + impl_->crossSourceCollisions = enableCollisions; return *this; } -const std::string& MapOptions::cachePath() const { - return impl_->cachePath; +bool MapOptions::crossSourceCollisions() const { + return impl_->crossSourceCollisions; } -MapOptions& MapOptions::withAssetRoot(std::string path) { - impl_->assetRoot = std::move(path); +MapOptions& MapOptions::withNorthOrientation(NorthOrientation orientation) { + impl_->orientation = orientation; return *this; } -const std::string& MapOptions::assetRoot() const { - return impl_->assetRoot; +NorthOrientation MapOptions::northOrientation() const { + return impl_->orientation; } -MapOptions& MapOptions::withMaximumCacheSize(uint64_t size) { - impl_->maximumSize = size; +MapOptions& MapOptions::withSize(Size size_) { + impl_->size = size_; return *this; } -uint64_t MapOptions::maximumCacheSize() const { - return impl_->maximumSize; +Size MapOptions::size() const { + return impl_->size; } -MapOptions& MapOptions::withCrossSourceCollisions(bool enableCollisions) { - impl_->crossSourceCollisions = enableCollisions; +MapOptions& MapOptions::withPixelRatio(float ratio) { + impl_->pixelRatio = ratio; return *this; } -bool MapOptions::crossSourceCollisions() const { - return impl_->crossSourceCollisions; +float MapOptions::pixelRatio() const { + return impl_->pixelRatio; } } // namespace mbgl diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index 6106eedb53..803a9db503 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -7,52 +7,54 @@ namespace attributes { // Layout attributes -MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_pos); -MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_extrude); -MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_pos_offset); -MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_pos_normal); -MBGL_DEFINE_ATTRIBUTE(float, 3, a_projected_pos); -MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_label_pos); -MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_anchor_pos); -MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos); -MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_normal_ed); -MBGL_DEFINE_ATTRIBUTE(uint8_t, 1, a_fade_opacity); -MBGL_DEFINE_ATTRIBUTE(uint8_t, 2, a_placed); -MBGL_DEFINE_ATTRIBUTE(uint16_t, 3, a_size); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_offset); -MBGL_DEFINE_ATTRIBUTE(float, 2, a_shift); +MBGL_DEFINE_ATTRIBUTE(int16_t, 2, pos); +MBGL_DEFINE_ATTRIBUTE(int16_t, 2, extrude); +MBGL_DEFINE_ATTRIBUTE(int16_t, 4, pos_offset); +MBGL_DEFINE_ATTRIBUTE(int16_t, 4, pos_normal); +MBGL_DEFINE_ATTRIBUTE(float, 3, projected_pos); +MBGL_DEFINE_ATTRIBUTE(int16_t, 2, label_pos); +MBGL_DEFINE_ATTRIBUTE(int16_t, 2, anchor_pos); +MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, texture_pos); +MBGL_DEFINE_ATTRIBUTE(int16_t, 4, normal_ed); +MBGL_DEFINE_ATTRIBUTE(uint8_t, 1, fade_opacity); +MBGL_DEFINE_ATTRIBUTE(uint8_t, 2, placed); +MBGL_DEFINE_ATTRIBUTE(uint16_t, 3, size); +MBGL_DEFINE_ATTRIBUTE(float, 1, offset); +MBGL_DEFINE_ATTRIBUTE(float, 2, shift); template <typename T, std::size_t N> -struct a_data { +struct data { using Type = gfx::AttributeType<T, N>; - static auto name() { return "a_data"; } + static constexpr auto name() { + return "data"; + } }; // Paint attributes -MBGL_DEFINE_ATTRIBUTE(float, 2, a_color); -MBGL_DEFINE_ATTRIBUTE(float, 2, a_fill_color); -MBGL_DEFINE_ATTRIBUTE(float, 2, a_halo_color); -MBGL_DEFINE_ATTRIBUTE(float, 2, a_stroke_color); -MBGL_DEFINE_ATTRIBUTE(float, 2, a_outline_color); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_opacity); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_stroke_opacity); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_blur); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_radius); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_width); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_floorwidth); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_height); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_base); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_gapwidth); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_stroke_width); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_halo_width); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_halo_blur); -MBGL_DEFINE_ATTRIBUTE(float, 1, a_weight); -MBGL_DEFINE_ATTRIBUTE(uint16_t, 4, a_pattern_to); -MBGL_DEFINE_ATTRIBUTE(uint16_t, 4, a_pattern_from); +MBGL_DEFINE_ATTRIBUTE(float, 2, color); +MBGL_DEFINE_ATTRIBUTE(float, 2, fill_color); +MBGL_DEFINE_ATTRIBUTE(float, 2, halo_color); +MBGL_DEFINE_ATTRIBUTE(float, 2, stroke_color); +MBGL_DEFINE_ATTRIBUTE(float, 2, outline_color); +MBGL_DEFINE_ATTRIBUTE(float, 1, opacity); +MBGL_DEFINE_ATTRIBUTE(float, 1, stroke_opacity); +MBGL_DEFINE_ATTRIBUTE(float, 1, blur); +MBGL_DEFINE_ATTRIBUTE(float, 1, radius); +MBGL_DEFINE_ATTRIBUTE(float, 1, width); +MBGL_DEFINE_ATTRIBUTE(float, 1, floorwidth); +MBGL_DEFINE_ATTRIBUTE(float, 1, height); +MBGL_DEFINE_ATTRIBUTE(float, 1, base); +MBGL_DEFINE_ATTRIBUTE(float, 1, gapwidth); +MBGL_DEFINE_ATTRIBUTE(float, 1, stroke_width); +MBGL_DEFINE_ATTRIBUTE(float, 1, halo_width); +MBGL_DEFINE_ATTRIBUTE(float, 1, halo_blur); +MBGL_DEFINE_ATTRIBUTE(float, 1, weight); +MBGL_DEFINE_ATTRIBUTE(uint16_t, 4, pattern_to); +MBGL_DEFINE_ATTRIBUTE(uint16_t, 4, pattern_from); } // namespace attributes -using PositionOnlyLayoutAttributes = TypeList<attributes::a_pos>; +using PositionOnlyLayoutAttributes = TypeList<attributes::pos>; } // namespace mbgl diff --git a/src/mbgl/programs/background_program.cpp b/src/mbgl/programs/background_program.cpp index 7d68f62fb1..772d481578 100644 --- a/src/mbgl/programs/background_program.cpp +++ b/src/mbgl/programs/background_program.cpp @@ -28,21 +28,21 @@ BackgroundPatternProgram::layoutUniformValues(mat4 matrix, int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y; return { - uniforms::u_matrix::Value( matrix ), - uniforms::u_opacity::Value( opacity ), - uniforms::u_texsize::Value( atlasSize ), - uniforms::u_pattern_tl_a::Value( a.tl() ), - uniforms::u_pattern_br_a::Value( a.br() ), - uniforms::u_pattern_tl_b::Value( b.tl() ), - uniforms::u_pattern_br_b::Value( b.br() ), - uniforms::u_pattern_size_a::Value( a.displaySize() ), - uniforms::u_pattern_size_b::Value( b.displaySize() ), - uniforms::u_scale_a::Value( fading.fromScale ), - uniforms::u_scale_b::Value( fading.toScale ), - uniforms::u_mix::Value( fading.t ), - uniforms::u_pixel_coord_upper::Value( std::array<float, 2> {{ float(pixelX >> 16), float(pixelY >> 16) }}), - uniforms::u_pixel_coord_lower::Value( std::array<float, 2> {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF)}}), - uniforms::u_tile_units_to_pixels::Value( 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom()) ), + uniforms::matrix::Value( matrix ), + uniforms::opacity::Value( opacity ), + uniforms::texsize::Value( atlasSize ), + uniforms::pattern_tl_a::Value( a.tl() ), + uniforms::pattern_br_a::Value( a.br() ), + uniforms::pattern_tl_b::Value( b.tl() ), + uniforms::pattern_br_b::Value( b.br() ), + uniforms::pattern_size_a::Value( a.displaySize() ), + uniforms::pattern_size_b::Value( b.displaySize() ), + uniforms::scale_a::Value( fading.fromScale ), + uniforms::scale_b::Value( fading.toScale ), + uniforms::mix::Value( fading.t ), + uniforms::pixel_coord_upper::Value( std::array<float, 2> {{ float(pixelX >> 16), float(pixelY >> 16) }}), + uniforms::pixel_coord_lower::Value( std::array<float, 2> {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF)}}), + uniforms::tile_units_to_pixels::Value( 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom()) ), }; } diff --git a/src/mbgl/programs/background_program.hpp b/src/mbgl/programs/background_program.hpp index b1ade6dc84..dd0683776c 100644 --- a/src/mbgl/programs/background_program.hpp +++ b/src/mbgl/programs/background_program.hpp @@ -18,26 +18,26 @@ template <class> class Faded; using BackgroundLayoutAttributes = PositionOnlyLayoutAttributes; using BackgroundUniforms = TypeList< - uniforms::u_matrix, - uniforms::u_color, - uniforms::u_opacity>; + uniforms::matrix, + uniforms::color, + uniforms::opacity>; using BackgroundPatternUniforms = TypeList< - uniforms::u_matrix, - uniforms::u_opacity, - uniforms::u_texsize, - uniforms::u_pattern_tl_a, - uniforms::u_pattern_br_a, - uniforms::u_pattern_tl_b, - uniforms::u_pattern_br_b, - uniforms::u_pattern_size_a, - uniforms::u_pattern_size_b, - uniforms::u_scale_a, - uniforms::u_scale_b, - uniforms::u_mix, - uniforms::u_pixel_coord_upper, - uniforms::u_pixel_coord_lower, - uniforms::u_tile_units_to_pixels>; + uniforms::matrix, + uniforms::opacity, + uniforms::texsize, + uniforms::pattern_tl_a, + uniforms::pattern_br_a, + uniforms::pattern_tl_b, + uniforms::pattern_br_b, + uniforms::pattern_size_a, + uniforms::pattern_size_b, + uniforms::scale_a, + uniforms::scale_b, + uniforms::mix, + uniforms::pixel_coord_upper, + uniforms::pixel_coord_lower, + uniforms::tile_units_to_pixels>; class BackgroundProgram : public Program< BackgroundProgram, @@ -57,7 +57,7 @@ class BackgroundPatternProgram : public Program< BackgroundLayoutAttributes, BackgroundPatternUniforms, TypeList< - textures::u_image>, + textures::image>, style::Properties<>> { public: diff --git a/src/mbgl/programs/circle_program.hpp b/src/mbgl/programs/circle_program.hpp index 0caa1b2a15..2b218d1768 100644 --- a/src/mbgl/programs/circle_program.hpp +++ b/src/mbgl/programs/circle_program.hpp @@ -9,20 +9,20 @@ namespace mbgl { namespace uniforms { -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_scale_with_map); +MBGL_DEFINE_UNIFORM_SCALAR(bool, scale_with_map); } // namespace uniforms class CircleProgram : public Program< CircleProgram, gfx::PrimitiveType::Triangle, TypeList< - attributes::a_pos>, + attributes::pos>, TypeList< - uniforms::u_matrix, - uniforms::u_scale_with_map, - uniforms::u_extrude_scale, - uniforms::u_camera_to_center_distance, - uniforms::u_pitch_with_map>, + uniforms::matrix, + uniforms::scale_with_map, + uniforms::extrude_scale, + uniforms::camera_to_center_distance, + uniforms::pitch_with_map>, TypeList<>, style::CirclePaintProperties> { @@ -52,7 +52,7 @@ class CircleLayerPrograms final : public LayerTypePrograms { public: CircleLayerPrograms(gfx::Context& context, const ProgramParameters& programParameters) : circle(context, programParameters) {} - ProgramMap<CircleProgram> circle; + CircleProgram circle; }; } // namespace mbgl diff --git a/src/mbgl/programs/clipping_mask_program.hpp b/src/mbgl/programs/clipping_mask_program.hpp index 874708a52f..14d66a8703 100644 --- a/src/mbgl/programs/clipping_mask_program.hpp +++ b/src/mbgl/programs/clipping_mask_program.hpp @@ -12,7 +12,7 @@ class ClippingMaskProgram : public Program< gfx::PrimitiveType::Triangle, PositionOnlyLayoutAttributes, TypeList< - uniforms::u_matrix>, + uniforms::matrix>, TypeList<>, style::Properties<>> { diff --git a/src/mbgl/programs/collision_box_program.hpp b/src/mbgl/programs/collision_box_program.hpp index 7b81752a94..677704b154 100644 --- a/src/mbgl/programs/collision_box_program.hpp +++ b/src/mbgl/programs/collision_box_program.hpp @@ -11,21 +11,20 @@ namespace mbgl { using CollisionBoxLayoutAttributes = TypeList< - attributes::a_pos, - attributes::a_anchor_pos, - attributes::a_extrude, - attributes::a_shift>; + attributes::pos, + attributes::anchor_pos, + attributes::extrude>; -using CollisionBoxDynamicAttributes = TypeList<attributes::a_placed>; +using CollisionBoxDynamicAttributes = TypeList<attributes::placed, attributes::shift>; class CollisionBoxProgram : public Program< CollisionBoxProgram, gfx::PrimitiveType::Line, TypeListConcat<CollisionBoxLayoutAttributes, CollisionBoxDynamicAttributes>, TypeList< - uniforms::u_matrix, - uniforms::u_extrude_scale, - uniforms::u_camera_to_center_distance>, + uniforms::matrix, + uniforms::extrude_scale, + uniforms::camera_to_center_distance>, TypeList<>, style::Properties<>> { @@ -45,17 +44,14 @@ public: {{ static_cast<int16_t>(::round(o.x)), static_cast<int16_t>(::round(o.y)) - }}, - {{ - 0.0f, - 0.0f }} }; } - static gfx::Vertex<CollisionBoxDynamicAttributes> dynamicVertex(bool placed, bool notUsed) { + static gfx::Vertex<CollisionBoxDynamicAttributes> dynamicVertex(bool placed, bool notUsed, Point<float> shift) { return { - {{ static_cast<uint8_t>(placed), static_cast<uint8_t>(notUsed) }} + {{ static_cast<uint8_t>(placed), static_cast<uint8_t>(notUsed) }}, + {{ shift.x, shift.y }} }; } @@ -116,10 +112,10 @@ class CollisionCircleProgram : public Program< gfx::PrimitiveType::Triangle, TypeListConcat<CollisionBoxLayoutAttributes, CollisionBoxDynamicAttributes>, TypeList< - uniforms::u_matrix, - uniforms::u_extrude_scale, - uniforms::u_overscale_factor, - uniforms::u_camera_to_center_distance>, + uniforms::matrix, + uniforms::extrude_scale, + uniforms::overscale_factor, + uniforms::camera_to_center_distance>, TypeList<>, style::Properties<>> { @@ -139,10 +135,6 @@ public: {{ static_cast<int16_t>(::round(o.x)), static_cast<int16_t>(::round(o.y)) - }}, - {{ - 0.0f, - 0.0f }} }; } diff --git a/src/mbgl/programs/debug_program.hpp b/src/mbgl/programs/debug_program.hpp index 61125b55bf..f1782e19e3 100644 --- a/src/mbgl/programs/debug_program.hpp +++ b/src/mbgl/programs/debug_program.hpp @@ -11,10 +11,10 @@ class DebugProgram : public Program< DebugProgram, gfx::PrimitiveType::Line, TypeList< - attributes::a_pos>, + attributes::pos>, TypeList< - uniforms::u_matrix, - uniforms::u_color>, + uniforms::matrix, + uniforms::color>, TypeList<>, style::Properties<>> { diff --git a/src/mbgl/programs/extrusion_texture_program.hpp b/src/mbgl/programs/extrusion_texture_program.hpp index bdeeabb8cd..10dfdc8a16 100644 --- a/src/mbgl/programs/extrusion_texture_program.hpp +++ b/src/mbgl/programs/extrusion_texture_program.hpp @@ -12,13 +12,13 @@ namespace mbgl { class ExtrusionTextureProgram : public Program< ExtrusionTextureProgram, gfx::PrimitiveType::Triangle, - TypeList<attributes::a_pos>, + TypeList<attributes::pos>, TypeList< - uniforms::u_matrix, - uniforms::u_world, - uniforms::u_opacity>, + uniforms::matrix, + uniforms::world, + uniforms::opacity>, TypeList< - textures::u_image>, + textures::image>, style::Properties<>> { public: using Program::Program; diff --git a/src/mbgl/programs/fill_extrusion_program.cpp b/src/mbgl/programs/fill_extrusion_program.cpp index 7688d09299..d301f32707 100644 --- a/src/mbgl/programs/fill_extrusion_program.cpp +++ b/src/mbgl/programs/fill_extrusion_program.cpp @@ -38,10 +38,10 @@ float lightIntensity(const EvaluatedLight& light) { FillExtrusionProgram::LayoutUniformValues FillExtrusionProgram::layoutUniformValues( mat4 matrix, const TransformState& state, const EvaluatedLight& light) { return { - uniforms::u_matrix::Value( matrix ), - uniforms::u_lightcolor::Value( lightColor(light) ), - uniforms::u_lightpos::Value( lightPosition(light, state) ), - uniforms::u_lightintensity::Value( lightIntensity(light) ) + uniforms::matrix::Value( matrix ), + uniforms::lightcolor::Value( lightColor(light) ), + uniforms::lightpos::Value( lightPosition(light, state) ), + uniforms::lightintensity::Value( lightIntensity(light) ) }; } @@ -60,16 +60,16 @@ FillExtrusionPatternProgram::layoutUniformValues(mat4 matrix, int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y; return { - uniforms::u_matrix::Value( matrix ), - uniforms::u_scale::Value( {{pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale}} ), - uniforms::u_texsize::Value( atlasSize ), - uniforms::u_fade::Value( crossfade.t ), - uniforms::u_pixel_coord_upper::Value( std::array<float, 2>{{ float(pixelX >> 16), float(pixelY >> 16) }} ), - uniforms::u_pixel_coord_lower::Value( std::array<float, 2>{{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} ), - uniforms::u_height_factor::Value( heightFactor ), - uniforms::u_lightcolor::Value( lightColor(light) ), - uniforms::u_lightpos::Value( lightPosition(light, state) ), - uniforms::u_lightintensity::Value( lightIntensity(light) ), + uniforms::matrix::Value( matrix ), + uniforms::scale::Value( {{pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale}} ), + uniforms::texsize::Value( atlasSize ), + uniforms::fade::Value( crossfade.t ), + uniforms::pixel_coord_upper::Value( std::array<float, 2>{{ float(pixelX >> 16), float(pixelY >> 16) }} ), + uniforms::pixel_coord_lower::Value( std::array<float, 2>{{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} ), + uniforms::height_factor::Value( heightFactor ), + uniforms::lightcolor::Value( lightColor(light) ), + uniforms::lightpos::Value( lightPosition(light, state) ), + uniforms::lightintensity::Value( lightIntensity(light) ), }; } diff --git a/src/mbgl/programs/fill_extrusion_program.hpp b/src/mbgl/programs/fill_extrusion_program.hpp index e1c3ca7f17..85e2ff3caf 100644 --- a/src/mbgl/programs/fill_extrusion_program.hpp +++ b/src/mbgl/programs/fill_extrusion_program.hpp @@ -22,33 +22,33 @@ class TransformState; template <class> class Faded; namespace uniforms { -MBGL_DEFINE_UNIFORM_VECTOR(float, 3, u_lightpos); -MBGL_DEFINE_UNIFORM_VECTOR(float, 3, u_lightcolor); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_lightintensity); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_height_factor); +MBGL_DEFINE_UNIFORM_VECTOR(float, 3, lightpos); +MBGL_DEFINE_UNIFORM_VECTOR(float, 3, lightcolor); +MBGL_DEFINE_UNIFORM_SCALAR(float, lightintensity); +MBGL_DEFINE_UNIFORM_SCALAR(float, height_factor); } // namespace uniforms using FillExtrusionLayoutAttributes = TypeList< - attributes::a_pos, - attributes::a_normal_ed>; + attributes::pos, + attributes::normal_ed>; using FillExtrusionUniforms = TypeList< - uniforms::u_matrix, - uniforms::u_lightcolor, - uniforms::u_lightpos, - uniforms::u_lightintensity>; + uniforms::matrix, + uniforms::lightcolor, + uniforms::lightpos, + uniforms::lightintensity>; using FillExtrusionPatternUniforms = TypeList< - uniforms::u_matrix, - uniforms::u_scale, - uniforms::u_texsize, - uniforms::u_fade, - uniforms::u_pixel_coord_upper, - uniforms::u_pixel_coord_lower, - uniforms::u_height_factor, - uniforms::u_lightcolor, - uniforms::u_lightpos, - uniforms::u_lightintensity>; + uniforms::matrix, + uniforms::scale, + uniforms::texsize, + uniforms::fade, + uniforms::pixel_coord_upper, + uniforms::pixel_coord_lower, + uniforms::height_factor, + uniforms::lightcolor, + uniforms::lightpos, + uniforms::lightintensity>; class FillExtrusionProgram : public Program< FillExtrusionProgram, @@ -91,7 +91,7 @@ class FillExtrusionPatternProgram : public Program< FillExtrusionLayoutAttributes, FillExtrusionPatternUniforms, TypeList< - textures::u_image>, + textures::image>, style::FillExtrusionPaintProperties> { public: @@ -117,8 +117,8 @@ public: : fillExtrusion(context, programParameters), fillExtrusionPattern(context, programParameters), extrusionTexture(context, programParameters) {} - ProgramMap<FillExtrusionProgram> fillExtrusion; - ProgramMap<FillExtrusionPatternProgram> fillExtrusionPattern; + FillExtrusionProgram fillExtrusion; + FillExtrusionPatternProgram fillExtrusionPattern; ExtrusionTextureProgram extrusionTexture; }; diff --git a/src/mbgl/programs/fill_program.cpp b/src/mbgl/programs/fill_program.cpp index e0dfc71f81..703d61399f 100644 --- a/src/mbgl/programs/fill_program.cpp +++ b/src/mbgl/programs/fill_program.cpp @@ -30,13 +30,13 @@ FillPatternProgram::layoutUniformValues(mat4 matrix, int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y; return { - uniforms::u_matrix::Value( matrix ), - uniforms::u_world::Value( framebufferSize ), - uniforms::u_texsize::Value( atlasSize ), - uniforms::u_scale::Value({ {pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale} } ), - uniforms::u_fade::Value( crossfade.t ), - uniforms::u_pixel_coord_upper::Value( std::array<float, 2> {{ float(pixelX >> 16), float(pixelY >> 16) }}), - uniforms::u_pixel_coord_lower::Value( std::array<float, 2> {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} ) + uniforms::matrix::Value( matrix ), + uniforms::world::Value( framebufferSize ), + uniforms::texsize::Value( atlasSize ), + uniforms::scale::Value({ {pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale} } ), + uniforms::fade::Value( crossfade.t ), + uniforms::pixel_coord_upper::Value( std::array<float, 2> {{ float(pixelX >> 16), float(pixelY >> 16) }}), + uniforms::pixel_coord_lower::Value( std::array<float, 2> {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} ) }; } diff --git a/src/mbgl/programs/fill_program.hpp b/src/mbgl/programs/fill_program.hpp index 8519e482d6..99314c51b0 100644 --- a/src/mbgl/programs/fill_program.hpp +++ b/src/mbgl/programs/fill_program.hpp @@ -21,17 +21,17 @@ template <class> class Faded; using FillLayoutAttributes = PositionOnlyLayoutAttributes; using FillUniforms = TypeList< - uniforms::u_matrix, - uniforms::u_world>; + uniforms::matrix, + uniforms::world>; using FillPatternUniforms = TypeList< - uniforms::u_matrix, - uniforms::u_world, - uniforms::u_texsize, - uniforms::u_scale, - uniforms::u_fade, - uniforms::u_pixel_coord_upper, - uniforms::u_pixel_coord_lower>; + uniforms::matrix, + uniforms::world, + uniforms::texsize, + uniforms::scale, + uniforms::fade, + uniforms::pixel_coord_upper, + uniforms::pixel_coord_lower>; class FillProgram : public Program< FillProgram, @@ -60,7 +60,7 @@ class FillPatternProgram : public Program< FillLayoutAttributes, FillPatternUniforms, TypeList< - textures::u_image>, + textures::image>, style::FillPaintProperties> { public: @@ -93,7 +93,7 @@ class FillOutlinePatternProgram : public Program< FillLayoutAttributes, FillPatternUniforms, TypeList< - textures::u_image>, + textures::image>, style::FillPaintProperties> { public: @@ -110,10 +110,10 @@ public: fillPattern(context, programParameters), fillOutline(context, programParameters), fillOutlinePattern(context, programParameters) {} - ProgramMap<FillProgram> fill; - ProgramMap<FillPatternProgram> fillPattern; - ProgramMap<FillOutlineProgram> fillOutline; - ProgramMap<FillOutlinePatternProgram> fillOutlinePattern; + FillProgram fill; + FillPatternProgram fillPattern; + FillOutlineProgram fillOutline; + FillOutlinePatternProgram fillOutlinePattern; }; } // namespace mbgl diff --git a/src/mbgl/programs/gl/background.cpp b/src/mbgl/programs/gl/background.cpp index da5ea25410..78074d670f 100644 --- a/src/mbgl/programs/gl/background.cpp +++ b/src/mbgl/programs/gl/background.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/background_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<BackgroundProgram> { + static constexpr const char* name = "background"; + static constexpr const uint8_t hash[8] = { 0x2d, 0xef, 0x97, 0xa2, 0xec, 0xb5, 0x67, 0xef }; + static constexpr const auto vertexOffset = 1429; + static constexpr const auto fragmentOffset = 1525; +}; + +constexpr const char* ShaderSource<BackgroundProgram>::name; +constexpr const uint8_t ShaderSource<BackgroundProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<BackgroundProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<BackgroundProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "background", - programs::gl::shaderSource() + 1429, programs::gl::shaderSource() + 1525); + return std::make_unique<gl::Program<BackgroundProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/background_pattern.cpp b/src/mbgl/programs/gl/background_pattern.cpp index af5d87129e..04111c7abd 100644 --- a/src/mbgl/programs/gl/background_pattern.cpp +++ b/src/mbgl/programs/gl/background_pattern.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/background_pattern_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<BackgroundPatternProgram> { + static constexpr const char* name = "background_pattern"; + static constexpr const uint8_t hash[8] = { 0x70, 0x13, 0xc8, 0x7e, 0xba, 0x18, 0xf5, 0x19 }; + static constexpr const auto vertexOffset = 1675; + static constexpr const auto fragmentOffset = 2266; +}; + +constexpr const char* ShaderSource<BackgroundPatternProgram>::name; +constexpr const uint8_t ShaderSource<BackgroundPatternProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<BackgroundPatternProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<BackgroundPatternProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "background_pattern", - programs::gl::shaderSource() + 1675, programs::gl::shaderSource() + 2266); + return std::make_unique<gl::Program<BackgroundPatternProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/circle.cpp b/src/mbgl/programs/gl/circle.cpp index 04c3f60870..d1f1e29d33 100644 --- a/src/mbgl/programs/gl/circle.cpp +++ b/src/mbgl/programs/gl/circle.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/circle_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<CircleProgram> { + static constexpr const char* name = "circle"; + static constexpr const uint8_t hash[8] = { 0xf0, 0x3e, 0x18, 0xb7, 0x75, 0xb2, 0xde, 0xa9 }; + static constexpr const auto vertexOffset = 2927; + static constexpr const auto fragmentOffset = 6093; +}; + +constexpr const char* ShaderSource<CircleProgram>::name; +constexpr const uint8_t ShaderSource<CircleProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<CircleProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<CircleProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "circle", - programs::gl::shaderSource() + 2927, programs::gl::shaderSource() + 6093); + return std::make_unique<gl::Program<CircleProgram>>(programParameters); } } // namespace gfx @@ -30,7 +49,7 @@ attribute vec2 a_pos; #ifndef HAS_UNIFORM_u_color -uniform lowp float a_color_t; +uniform lowp float u_color_t; attribute highp vec4 a_color; varying highp vec4 color; #else @@ -39,7 +58,7 @@ uniform highp vec4 u_color; #ifndef HAS_UNIFORM_u_radius -uniform lowp float a_radius_t; +uniform lowp float u_radius_t; attribute mediump vec2 a_radius; varying mediump float radius; #else @@ -48,7 +67,7 @@ uniform mediump float u_radius; #ifndef HAS_UNIFORM_u_blur -uniform lowp float a_blur_t; +uniform lowp float u_blur_t; attribute lowp vec2 a_blur; varying lowp float blur; #else @@ -57,7 +76,7 @@ uniform lowp float u_blur; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -66,7 +85,7 @@ uniform lowp float u_opacity; #ifndef HAS_UNIFORM_u_stroke_color -uniform lowp float a_stroke_color_t; +uniform lowp float u_stroke_color_t; attribute highp vec4 a_stroke_color; varying highp vec4 stroke_color; #else @@ -75,7 +94,7 @@ uniform highp vec4 u_stroke_color; #ifndef HAS_UNIFORM_u_stroke_width -uniform lowp float a_stroke_width_t; +uniform lowp float u_stroke_width_t; attribute mediump vec2 a_stroke_width; varying mediump float stroke_width; #else @@ -84,7 +103,7 @@ uniform mediump float u_stroke_width; #ifndef HAS_UNIFORM_u_stroke_opacity -uniform lowp float a_stroke_opacity_t; +uniform lowp float u_stroke_opacity_t; attribute lowp vec2 a_stroke_opacity; varying lowp float stroke_opacity; #else @@ -97,49 +116,49 @@ varying vec3 v_data; void main(void) { #ifndef HAS_UNIFORM_u_color - color = unpack_mix_color(a_color, a_color_t); + color = unpack_mix_color(a_color, u_color_t); #else highp vec4 color = u_color; #endif #ifndef HAS_UNIFORM_u_radius - radius = unpack_mix_vec2(a_radius, a_radius_t); + radius = unpack_mix_vec2(a_radius, u_radius_t); #else mediump float radius = u_radius; #endif #ifndef HAS_UNIFORM_u_blur - blur = unpack_mix_vec2(a_blur, a_blur_t); + blur = unpack_mix_vec2(a_blur, u_blur_t); #else lowp float blur = u_blur; #endif #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif #ifndef HAS_UNIFORM_u_stroke_color - stroke_color = unpack_mix_color(a_stroke_color, a_stroke_color_t); + stroke_color = unpack_mix_color(a_stroke_color, u_stroke_color_t); #else highp vec4 stroke_color = u_stroke_color; #endif #ifndef HAS_UNIFORM_u_stroke_width - stroke_width = unpack_mix_vec2(a_stroke_width, a_stroke_width_t); + stroke_width = unpack_mix_vec2(a_stroke_width, u_stroke_width_t); #else mediump float stroke_width = u_stroke_width; #endif #ifndef HAS_UNIFORM_u_stroke_opacity - stroke_opacity = unpack_mix_vec2(a_stroke_opacity, a_stroke_opacity_t); + stroke_opacity = unpack_mix_vec2(a_stroke_opacity, u_stroke_opacity_t); #else lowp float stroke_opacity = u_stroke_opacity; #endif diff --git a/src/mbgl/programs/gl/clipping_mask.cpp b/src/mbgl/programs/gl/clipping_mask.cpp index 311877f065..3179ab0c13 100644 --- a/src/mbgl/programs/gl/clipping_mask.cpp +++ b/src/mbgl/programs/gl/clipping_mask.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/clipping_mask_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<ClippingMaskProgram> { + static constexpr const char* name = "clipping_mask"; + static constexpr const uint8_t hash[8] = { 0x3e, 0x17, 0xc2, 0x3a, 0x1f, 0xf0, 0xa8, 0xa3 }; + static constexpr const auto vertexOffset = 7848; + static constexpr const auto fragmentOffset = 7944; +}; + +constexpr const char* ShaderSource<ClippingMaskProgram>::name; +constexpr const uint8_t ShaderSource<ClippingMaskProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<ClippingMaskProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<ClippingMaskProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "clipping_mask", - programs::gl::shaderSource() + 7848, programs::gl::shaderSource() + 7944); + return std::make_unique<gl::Program<ClippingMaskProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/collision_box.cpp b/src/mbgl/programs/gl/collision_box.cpp index 9af67f7981..f7ac4d4d67 100644 --- a/src/mbgl/programs/gl/collision_box.cpp +++ b/src/mbgl/programs/gl/collision_box.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/collision_box_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<CollisionBoxProgram> { + static constexpr const char* name = "collision_box"; + static constexpr const uint8_t hash[8] = { 0xcb, 0x6a, 0x9b, 0xd1, 0x1f, 0x31, 0xf8, 0x5b }; + static constexpr const auto vertexOffset = 9956; + static constexpr const auto fragmentOffset = 10635; +}; + +constexpr const char* ShaderSource<CollisionBoxProgram>::name; +constexpr const uint8_t ShaderSource<CollisionBoxProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<CollisionBoxProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<CollisionBoxProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "collision_box", - programs::gl::shaderSource() + 9956, programs::gl::shaderSource() + 10635); + return std::make_unique<gl::Program<CollisionBoxProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/collision_circle.cpp b/src/mbgl/programs/gl/collision_circle.cpp index 843f9161bb..8f1b5726fe 100644 --- a/src/mbgl/programs/gl/collision_circle.cpp +++ b/src/mbgl/programs/gl/collision_circle.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/collision_circle_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<CollisionCircleProgram> { + static constexpr const char* name = "collision_circle"; + static constexpr const uint8_t hash[8] = { 0x99, 0x2e, 0xad, 0x8c, 0xd3, 0x88, 0xae, 0x82 }; + static constexpr const auto vertexOffset = 10858; + static constexpr const auto fragmentOffset = 11774; +}; + +constexpr const char* ShaderSource<CollisionCircleProgram>::name; +constexpr const uint8_t ShaderSource<CollisionCircleProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<CollisionCircleProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<CollisionCircleProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "collision_circle", - programs::gl::shaderSource() + 10858, programs::gl::shaderSource() + 11774); + return std::make_unique<gl::Program<CollisionCircleProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/debug.cpp b/src/mbgl/programs/gl/debug.cpp index 8b7aee5a0b..ad23f420ab 100644 --- a/src/mbgl/programs/gl/debug.cpp +++ b/src/mbgl/programs/gl/debug.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/debug_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<DebugProgram> { + static constexpr const char* name = "debug"; + static constexpr const uint8_t hash[8] = { 0xa8, 0x7d, 0x87, 0x6e, 0x36, 0xa8, 0x81, 0xe3 }; + static constexpr const auto vertexOffset = 12450; + static constexpr const auto fragmentOffset = 12546; +}; + +constexpr const char* ShaderSource<DebugProgram>::name; +constexpr const uint8_t ShaderSource<DebugProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<DebugProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<DebugProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "debug", - programs::gl::shaderSource() + 12450, programs::gl::shaderSource() + 12546); + return std::make_unique<gl::Program<DebugProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/extrusion_texture.cpp b/src/mbgl/programs/gl/extrusion_texture.cpp index bd320d52cf..bca533a788 100644 --- a/src/mbgl/programs/gl/extrusion_texture.cpp +++ b/src/mbgl/programs/gl/extrusion_texture.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/extrusion_texture_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<ExtrusionTextureProgram> { + static constexpr const char* name = "extrusion_texture"; + static constexpr const uint8_t hash[8] = { 0xd9, 0x77, 0x11, 0xd2, 0x03, 0xc7, 0x27, 0xcb }; + static constexpr const auto vertexOffset = 27554; + static constexpr const auto fragmentOffset = 27734; +}; + +constexpr const char* ShaderSource<ExtrusionTextureProgram>::name; +constexpr const uint8_t ShaderSource<ExtrusionTextureProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<ExtrusionTextureProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<ExtrusionTextureProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "extrusion_texture", - programs::gl::shaderSource() + 27554, programs::gl::shaderSource() + 27734); + return std::make_unique<gl::Program<ExtrusionTextureProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/fill.cpp b/src/mbgl/programs/gl/fill.cpp index c15c2774ab..a699f82609 100644 --- a/src/mbgl/programs/gl/fill.cpp +++ b/src/mbgl/programs/gl/fill.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/fill_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<FillProgram> { + static constexpr const char* name = "fill"; + static constexpr const uint8_t hash[8] = { 0x87, 0xea, 0x65, 0x7f, 0x0c, 0x9b, 0x97, 0x5d }; + static constexpr const auto vertexOffset = 12610; + static constexpr const auto fragmentOffset = 13254; +}; + +constexpr const char* ShaderSource<FillProgram>::name; +constexpr const uint8_t ShaderSource<FillProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<FillProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<FillProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "fill", - programs::gl::shaderSource() + 12610, programs::gl::shaderSource() + 13254); + return std::make_unique<gl::Program<FillProgram>>(programParameters); } } // namespace gfx @@ -26,7 +45,7 @@ uniform mat4 u_matrix; #ifndef HAS_UNIFORM_u_color -uniform lowp float a_color_t; +uniform lowp float u_color_t; attribute highp vec4 a_color; varying highp vec4 color; #else @@ -35,7 +54,7 @@ uniform highp vec4 u_color; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -46,14 +65,14 @@ uniform lowp float u_opacity; void main() { #ifndef HAS_UNIFORM_u_color - color = unpack_mix_color(a_color, a_color_t); + color = unpack_mix_color(a_color, u_color_t); #else highp vec4 color = u_color; #endif #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif diff --git a/src/mbgl/programs/gl/fill_extrusion.cpp b/src/mbgl/programs/gl/fill_extrusion.cpp index 45ebb68dd4..83a8eadee6 100644 --- a/src/mbgl/programs/gl/fill_extrusion.cpp +++ b/src/mbgl/programs/gl/fill_extrusion.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/fill_extrusion_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<FillExtrusionProgram> { + static constexpr const char* name = "fill_extrusion"; + static constexpr const uint8_t hash[8] = { 0x49, 0x8a, 0xa2, 0x8b, 0x21, 0x74, 0x27, 0x93 }; + static constexpr const auto vertexOffset = 21238; + static constexpr const auto fragmentOffset = 23121; +}; + +constexpr const char* ShaderSource<FillExtrusionProgram>::name; +constexpr const uint8_t ShaderSource<FillExtrusionProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<FillExtrusionProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<FillExtrusionProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "fill_extrusion", - programs::gl::shaderSource() + 21238, programs::gl::shaderSource() + 23121); + return std::make_unique<gl::Program<FillExtrusionProgram>>(programParameters); } } // namespace gfx @@ -33,7 +52,7 @@ varying vec4 v_color; #ifndef HAS_UNIFORM_u_base -uniform lowp float a_base_t; +uniform lowp float u_base_t; attribute highp vec2 a_base; #else uniform highp float u_base; @@ -41,7 +60,7 @@ uniform highp float u_base; #ifndef HAS_UNIFORM_u_height -uniform lowp float a_height_t; +uniform lowp float u_height_t; attribute highp vec2 a_height; #else uniform highp float u_height; @@ -50,7 +69,7 @@ uniform highp float u_height; #ifndef HAS_UNIFORM_u_color -uniform lowp float a_color_t; +uniform lowp float u_color_t; attribute highp vec4 a_color; #else uniform highp vec4 u_color; @@ -60,21 +79,21 @@ uniform highp vec4 u_color; void main() { #ifndef HAS_UNIFORM_u_base - highp float base = unpack_mix_vec2(a_base, a_base_t); + highp float base = unpack_mix_vec2(a_base, u_base_t); #else highp float base = u_base; #endif #ifndef HAS_UNIFORM_u_height - highp float height = unpack_mix_vec2(a_height, a_height_t); + highp float height = unpack_mix_vec2(a_height, u_height_t); #else highp float height = u_height; #endif #ifndef HAS_UNIFORM_u_color - highp vec4 color = unpack_mix_color(a_color, a_color_t); + highp vec4 color = unpack_mix_color(a_color, u_color_t); #else highp vec4 color = u_color; #endif diff --git a/src/mbgl/programs/gl/fill_extrusion_pattern.cpp b/src/mbgl/programs/gl/fill_extrusion_pattern.cpp index 9c2da87b11..45068d84b8 100644 --- a/src/mbgl/programs/gl/fill_extrusion_pattern.cpp +++ b/src/mbgl/programs/gl/fill_extrusion_pattern.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/fill_extrusion_pattern_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<FillExtrusionPatternProgram> { + static constexpr const char* name = "fill_extrusion_pattern"; + static constexpr const uint8_t hash[8] = { 0x93, 0x2b, 0xd1, 0xab, 0xa3, 0xf2, 0x24, 0x63 }; + static constexpr const auto vertexOffset = 23237; + static constexpr const auto fragmentOffset = 26157; +}; + +constexpr const char* ShaderSource<FillExtrusionPatternProgram>::name; +constexpr const uint8_t ShaderSource<FillExtrusionPatternProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<FillExtrusionPatternProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<FillExtrusionPatternProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "fill_extrusion_pattern", - programs::gl::shaderSource() + 23237, programs::gl::shaderSource() + 26157); + return std::make_unique<gl::Program<FillExtrusionPatternProgram>>(programParameters); } } // namespace gfx @@ -40,7 +59,7 @@ varying vec4 v_lighting; #ifndef HAS_UNIFORM_u_base -uniform lowp float a_base_t; +uniform lowp float u_base_t; attribute lowp vec2 a_base; varying lowp float base; #else @@ -49,7 +68,7 @@ uniform lowp float u_base; #ifndef HAS_UNIFORM_u_height -uniform lowp float a_height_t; +uniform lowp float u_height_t; attribute lowp vec2 a_height; varying lowp float height; #else @@ -58,7 +77,7 @@ uniform lowp float u_height; #ifndef HAS_UNIFORM_u_pattern_from -uniform lowp float a_pattern_from_t; +uniform lowp float u_pattern_from_t; attribute lowp vec4 a_pattern_from; varying lowp vec4 pattern_from; #else @@ -67,7 +86,7 @@ uniform lowp vec4 u_pattern_from; #ifndef HAS_UNIFORM_u_pattern_to -uniform lowp float a_pattern_to_t; +uniform lowp float u_pattern_to_t; attribute lowp vec4 a_pattern_to; varying lowp vec4 pattern_to; #else @@ -78,14 +97,14 @@ uniform lowp vec4 u_pattern_to; void main() { #ifndef HAS_UNIFORM_u_base - base = unpack_mix_vec2(a_base, a_base_t); + base = unpack_mix_vec2(a_base, u_base_t); #else lowp float base = u_base; #endif #ifndef HAS_UNIFORM_u_height - height = unpack_mix_vec2(a_height, a_height_t); + height = unpack_mix_vec2(a_height, u_height_t); #else lowp float height = u_height; #endif diff --git a/src/mbgl/programs/gl/fill_outline.cpp b/src/mbgl/programs/gl/fill_outline.cpp index 07615b2138..e7644468a5 100644 --- a/src/mbgl/programs/gl/fill_outline.cpp +++ b/src/mbgl/programs/gl/fill_outline.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/fill_outline_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<FillOutlineProgram> { + static constexpr const char* name = "fill_outline"; + static constexpr const uint8_t hash[8] = { 0x56, 0x65, 0x69, 0x4b, 0x70, 0x2d, 0x3d, 0xc4 }; + static constexpr const auto vertexOffset = 13678; + static constexpr const auto fragmentOffset = 14503; +}; + +constexpr const char* ShaderSource<FillOutlineProgram>::name; +constexpr const uint8_t ShaderSource<FillOutlineProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<FillOutlineProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<FillOutlineProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "fill_outline", - programs::gl::shaderSource() + 13678, programs::gl::shaderSource() + 14503); + return std::make_unique<gl::Program<FillOutlineProgram>>(programParameters); } } // namespace gfx @@ -29,7 +48,7 @@ varying vec2 v_pos; #ifndef HAS_UNIFORM_u_outline_color -uniform lowp float a_outline_color_t; +uniform lowp float u_outline_color_t; attribute highp vec4 a_outline_color; varying highp vec4 outline_color; #else @@ -38,7 +57,7 @@ uniform highp vec4 u_outline_color; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -49,14 +68,14 @@ uniform lowp float u_opacity; void main() { #ifndef HAS_UNIFORM_u_outline_color - outline_color = unpack_mix_color(a_outline_color, a_outline_color_t); + outline_color = unpack_mix_color(a_outline_color, u_outline_color_t); #else highp vec4 outline_color = u_outline_color; #endif #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif diff --git a/src/mbgl/programs/gl/fill_outline_pattern.cpp b/src/mbgl/programs/gl/fill_outline_pattern.cpp index 7e0bf19655..40aa5ea2de 100644 --- a/src/mbgl/programs/gl/fill_outline_pattern.cpp +++ b/src/mbgl/programs/gl/fill_outline_pattern.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/fill_outline_pattern_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<FillOutlinePatternProgram> { + static constexpr const char* name = "fill_outline_pattern"; + static constexpr const uint8_t hash[8] = { 0x56, 0x9c, 0x2f, 0x58, 0x6b, 0x31, 0xff, 0x84 }; + static constexpr const auto vertexOffset = 15092; + static constexpr const auto fragmentOffset = 16952; +}; + +constexpr const char* ShaderSource<FillOutlinePatternProgram>::name; +constexpr const uint8_t ShaderSource<FillOutlinePatternProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<FillOutlinePatternProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<FillOutlinePatternProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "fill_outline_pattern", - programs::gl::shaderSource() + 15092, programs::gl::shaderSource() + 16952); + return std::make_unique<gl::Program<FillOutlinePatternProgram>>(programParameters); } } // namespace gfx @@ -34,7 +53,7 @@ varying vec2 v_pos; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -43,7 +62,7 @@ uniform lowp float u_opacity; #ifndef HAS_UNIFORM_u_pattern_from -uniform lowp float a_pattern_from_t; +uniform lowp float u_pattern_from_t; attribute lowp vec4 a_pattern_from; varying lowp vec4 pattern_from; #else @@ -52,7 +71,7 @@ uniform lowp vec4 u_pattern_from; #ifndef HAS_UNIFORM_u_pattern_to -uniform lowp float a_pattern_to_t; +uniform lowp float u_pattern_to_t; attribute lowp vec4 a_pattern_to; varying lowp vec4 pattern_to; #else @@ -63,7 +82,7 @@ uniform lowp vec4 u_pattern_to; void main() { #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif diff --git a/src/mbgl/programs/gl/fill_pattern.cpp b/src/mbgl/programs/gl/fill_pattern.cpp index 256b1ede99..fd16d8bfc9 100644 --- a/src/mbgl/programs/gl/fill_pattern.cpp +++ b/src/mbgl/programs/gl/fill_pattern.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/fill_pattern_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<FillPatternProgram> { + static constexpr const char* name = "fill_pattern"; + static constexpr const uint8_t hash[8] = { 0x74, 0xa9, 0x97, 0x01, 0x96, 0xbd, 0x87, 0x36 }; + static constexpr const auto vertexOffset = 18259; + static constexpr const auto fragmentOffset = 20038; +}; + +constexpr const char* ShaderSource<FillPatternProgram>::name; +constexpr const uint8_t ShaderSource<FillPatternProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<FillPatternProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<FillPatternProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "fill_pattern", - programs::gl::shaderSource() + 18259, programs::gl::shaderSource() + 20038); + return std::make_unique<gl::Program<FillPatternProgram>>(programParameters); } } // namespace gfx @@ -32,7 +51,7 @@ varying vec2 v_pos_b; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -41,7 +60,7 @@ uniform lowp float u_opacity; #ifndef HAS_UNIFORM_u_pattern_from -uniform lowp float a_pattern_from_t; +uniform lowp float u_pattern_from_t; attribute lowp vec4 a_pattern_from; varying lowp vec4 pattern_from; #else @@ -50,7 +69,7 @@ uniform lowp vec4 u_pattern_from; #ifndef HAS_UNIFORM_u_pattern_to -uniform lowp float a_pattern_to_t; +uniform lowp float u_pattern_to_t; attribute lowp vec4 a_pattern_to; varying lowp vec4 pattern_to; #else @@ -61,7 +80,7 @@ uniform lowp vec4 u_pattern_to; void main() { #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif diff --git a/src/mbgl/programs/gl/heatmap.cpp b/src/mbgl/programs/gl/heatmap.cpp index 59f8ad9f69..3b960f1bda 100644 --- a/src/mbgl/programs/gl/heatmap.cpp +++ b/src/mbgl/programs/gl/heatmap.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/heatmap_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<HeatmapProgram> { + static constexpr const char* name = "heatmap"; + static constexpr const uint8_t hash[8] = { 0xab, 0x97, 0x81, 0x5c, 0xa2, 0x88, 0xaa, 0x7e }; + static constexpr const auto vertexOffset = 7983; + static constexpr const auto fragmentOffset = 9030; +}; + +constexpr const char* ShaderSource<HeatmapProgram>::name; +constexpr const uint8_t ShaderSource<HeatmapProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<HeatmapProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<HeatmapProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "heatmap", - programs::gl::shaderSource() + 7983, programs::gl::shaderSource() + 9030); + return std::make_unique<gl::Program<HeatmapProgram>>(programParameters); } } // namespace gfx @@ -22,7 +41,7 @@ Context::createProgram<gl::Context>(const ProgramParameters& programParameters) /* #ifndef HAS_UNIFORM_u_weight -uniform lowp float a_weight_t; +uniform lowp float u_weight_t; attribute highp vec2 a_weight; varying highp float weight; #else @@ -31,7 +50,7 @@ uniform highp float u_weight; #ifndef HAS_UNIFORM_u_radius -uniform lowp float a_radius_t; +uniform lowp float u_radius_t; attribute mediump vec2 a_radius; #else uniform mediump float u_radius; @@ -58,14 +77,14 @@ const highp float ZERO = 1.0 / 255.0 / 16.0; void main(void) { #ifndef HAS_UNIFORM_u_weight - weight = unpack_mix_vec2(a_weight, a_weight_t); + weight = unpack_mix_vec2(a_weight, u_weight_t); #else highp float weight = u_weight; #endif #ifndef HAS_UNIFORM_u_radius - mediump float radius = unpack_mix_vec2(a_radius, a_radius_t); + mediump float radius = unpack_mix_vec2(a_radius, u_radius_t); #else mediump float radius = u_radius; #endif diff --git a/src/mbgl/programs/gl/heatmap_texture.cpp b/src/mbgl/programs/gl/heatmap_texture.cpp index 530e9fa18b..57b033d55c 100644 --- a/src/mbgl/programs/gl/heatmap_texture.cpp +++ b/src/mbgl/programs/gl/heatmap_texture.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/heatmap_texture_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<HeatmapTextureProgram> { + static constexpr const char* name = "heatmap_texture"; + static constexpr const uint8_t hash[8] = { 0x9f, 0xc7, 0x56, 0xb2, 0x9e, 0x8f, 0x15, 0xff }; + static constexpr const auto vertexOffset = 9491; + static constexpr const auto fragmentOffset = 9671; +}; + +constexpr const char* ShaderSource<HeatmapTextureProgram>::name; +constexpr const uint8_t ShaderSource<HeatmapTextureProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<HeatmapTextureProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<HeatmapTextureProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "heatmap_texture", - programs::gl::shaderSource() + 9491, programs::gl::shaderSource() + 9671); + return std::make_unique<gl::Program<HeatmapTextureProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/hillshade.cpp b/src/mbgl/programs/gl/hillshade.cpp index dcf90f1149..a33ddb4326 100644 --- a/src/mbgl/programs/gl/hillshade.cpp +++ b/src/mbgl/programs/gl/hillshade.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/hillshade_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<HillshadeProgram> { + static constexpr const char* name = "hillshade"; + static constexpr const uint8_t hash[8] = { 0x8a, 0x11, 0x29, 0x18, 0x52, 0x7f, 0x3b, 0xbb }; + static constexpr const auto vertexOffset = 29340; + static constexpr const auto fragmentOffset = 29511; +}; + +constexpr const char* ShaderSource<HillshadeProgram>::name; +constexpr const uint8_t ShaderSource<HillshadeProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<HillshadeProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<HillshadeProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "hillshade", - programs::gl::shaderSource() + 29340, programs::gl::shaderSource() + 29511); + return std::make_unique<gl::Program<HillshadeProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/hillshade_prepare.cpp b/src/mbgl/programs/gl/hillshade_prepare.cpp index b445713530..a302db5feb 100644 --- a/src/mbgl/programs/gl/hillshade_prepare.cpp +++ b/src/mbgl/programs/gl/hillshade_prepare.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/hillshade_prepare_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<HillshadePrepareProgram> { + static constexpr const char* name = "hillshade_prepare"; + static constexpr const uint8_t hash[8] = { 0xe6, 0x01, 0xf2, 0xbb, 0xa0, 0x77, 0x1d, 0xeb }; + static constexpr const auto vertexOffset = 27925; + static constexpr const auto fragmentOffset = 28218; +}; + +constexpr const char* ShaderSource<HillshadePrepareProgram>::name; +constexpr const uint8_t ShaderSource<HillshadePrepareProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<HillshadePrepareProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<HillshadePrepareProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "hillshade_prepare", - programs::gl::shaderSource() + 27925, programs::gl::shaderSource() + 28218); + return std::make_unique<gl::Program<HillshadePrepareProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/line.cpp b/src/mbgl/programs/gl/line.cpp index c25679ae1f..e59cb07cb9 100644 --- a/src/mbgl/programs/gl/line.cpp +++ b/src/mbgl/programs/gl/line.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/line_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<LineProgram> { + static constexpr const char* name = "line"; + static constexpr const uint8_t hash[8] = { 0x44, 0x46, 0x9e, 0x59, 0x02, 0xbb, 0xaa, 0xae }; + static constexpr const auto vertexOffset = 30585; + static constexpr const auto fragmentOffset = 33509; +}; + +constexpr const char* ShaderSource<LineProgram>::name; +constexpr const uint8_t ShaderSource<LineProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<LineProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<LineProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "line", - programs::gl::shaderSource() + 30585, programs::gl::shaderSource() + 33509); + return std::make_unique<gl::Program<LineProgram>>(programParameters); } } // namespace gfx @@ -48,7 +67,7 @@ varying highp float v_linesofar; #ifndef HAS_UNIFORM_u_color -uniform lowp float a_color_t; +uniform lowp float u_color_t; attribute highp vec4 a_color; varying highp vec4 color; #else @@ -57,7 +76,7 @@ uniform highp vec4 u_color; #ifndef HAS_UNIFORM_u_blur -uniform lowp float a_blur_t; +uniform lowp float u_blur_t; attribute lowp vec2 a_blur; varying lowp float blur; #else @@ -66,7 +85,7 @@ uniform lowp float u_blur; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -75,7 +94,7 @@ uniform lowp float u_opacity; #ifndef HAS_UNIFORM_u_gapwidth -uniform lowp float a_gapwidth_t; +uniform lowp float u_gapwidth_t; attribute mediump vec2 a_gapwidth; #else uniform mediump float u_gapwidth; @@ -83,7 +102,7 @@ uniform mediump float u_gapwidth; #ifndef HAS_UNIFORM_u_offset -uniform lowp float a_offset_t; +uniform lowp float u_offset_t; attribute lowp vec2 a_offset; #else uniform lowp float u_offset; @@ -91,7 +110,7 @@ uniform lowp float u_offset; #ifndef HAS_UNIFORM_u_width -uniform lowp float a_width_t; +uniform lowp float u_width_t; attribute mediump vec2 a_width; #else uniform mediump float u_width; @@ -101,42 +120,42 @@ uniform mediump float u_width; void main() { #ifndef HAS_UNIFORM_u_color - color = unpack_mix_color(a_color, a_color_t); + color = unpack_mix_color(a_color, u_color_t); #else highp vec4 color = u_color; #endif #ifndef HAS_UNIFORM_u_blur - blur = unpack_mix_vec2(a_blur, a_blur_t); + blur = unpack_mix_vec2(a_blur, u_blur_t); #else lowp float blur = u_blur; #endif #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif #ifndef HAS_UNIFORM_u_gapwidth - mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); + mediump float gapwidth = unpack_mix_vec2(a_gapwidth, u_gapwidth_t); #else mediump float gapwidth = u_gapwidth; #endif #ifndef HAS_UNIFORM_u_offset - lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); + lowp float offset = unpack_mix_vec2(a_offset, u_offset_t); #else lowp float offset = u_offset; #endif #ifndef HAS_UNIFORM_u_width - mediump float width = unpack_mix_vec2(a_width, a_width_t); + mediump float width = unpack_mix_vec2(a_width, u_width_t); #else mediump float width = u_width; #endif diff --git a/src/mbgl/programs/gl/line_gradient.cpp b/src/mbgl/programs/gl/line_gradient.cpp index fae94b4596..f5325f84ba 100644 --- a/src/mbgl/programs/gl/line_gradient.cpp +++ b/src/mbgl/programs/gl/line_gradient.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/line_gradient_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<LineGradientProgram> { + static constexpr const char* name = "line_gradient"; + static constexpr const uint8_t hash[8] = { 0xee, 0xdd, 0x10, 0x3d, 0x1a, 0x21, 0x26, 0x25 }; + static constexpr const auto vertexOffset = 34335; + static constexpr const auto fragmentOffset = 37054; +}; + +constexpr const char* ShaderSource<LineGradientProgram>::name; +constexpr const uint8_t ShaderSource<LineGradientProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<LineGradientProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<LineGradientProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "line_gradient", - programs::gl::shaderSource() + 34335, programs::gl::shaderSource() + 37054); + return std::make_unique<gl::Program<LineGradientProgram>>(programParameters); } } // namespace gfx @@ -50,7 +69,7 @@ varying highp float v_lineprogress; #ifndef HAS_UNIFORM_u_blur -uniform lowp float a_blur_t; +uniform lowp float u_blur_t; attribute lowp vec2 a_blur; varying lowp float blur; #else @@ -59,7 +78,7 @@ uniform lowp float u_blur; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -68,7 +87,7 @@ uniform lowp float u_opacity; #ifndef HAS_UNIFORM_u_gapwidth -uniform lowp float a_gapwidth_t; +uniform lowp float u_gapwidth_t; attribute mediump vec2 a_gapwidth; #else uniform mediump float u_gapwidth; @@ -76,7 +95,7 @@ uniform mediump float u_gapwidth; #ifndef HAS_UNIFORM_u_offset -uniform lowp float a_offset_t; +uniform lowp float u_offset_t; attribute lowp vec2 a_offset; #else uniform lowp float u_offset; @@ -84,7 +103,7 @@ uniform lowp float u_offset; #ifndef HAS_UNIFORM_u_width -uniform lowp float a_width_t; +uniform lowp float u_width_t; attribute mediump vec2 a_width; #else uniform mediump float u_width; @@ -94,35 +113,35 @@ uniform mediump float u_width; void main() { #ifndef HAS_UNIFORM_u_blur - blur = unpack_mix_vec2(a_blur, a_blur_t); + blur = unpack_mix_vec2(a_blur, u_blur_t); #else lowp float blur = u_blur; #endif #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif #ifndef HAS_UNIFORM_u_gapwidth - mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); + mediump float gapwidth = unpack_mix_vec2(a_gapwidth, u_gapwidth_t); #else mediump float gapwidth = u_gapwidth; #endif #ifndef HAS_UNIFORM_u_offset - lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); + lowp float offset = unpack_mix_vec2(a_offset, u_offset_t); #else lowp float offset = u_offset; #endif #ifndef HAS_UNIFORM_u_width - mediump float width = unpack_mix_vec2(a_width, a_width_t); + mediump float width = unpack_mix_vec2(a_width, u_width_t); #else mediump float width = u_width; #endif diff --git a/src/mbgl/programs/gl/line_pattern.cpp b/src/mbgl/programs/gl/line_pattern.cpp index 2e9ebaf5ea..e323b16785 100644 --- a/src/mbgl/programs/gl/line_pattern.cpp +++ b/src/mbgl/programs/gl/line_pattern.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/line_pattern_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<LinePatternProgram> { + static constexpr const char* name = "line_pattern"; + static constexpr const uint8_t hash[8] = { 0x73, 0xa0, 0x59, 0x46, 0x57, 0xa5, 0x60, 0x25 }; + static constexpr const auto vertexOffset = 37841; + static constexpr const auto fragmentOffset = 41162; +}; + +constexpr const char* ShaderSource<LinePatternProgram>::name; +constexpr const uint8_t ShaderSource<LinePatternProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<LinePatternProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<LinePatternProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "line_pattern", - programs::gl::shaderSource() + 37841, programs::gl::shaderSource() + 41162); + return std::make_unique<gl::Program<LinePatternProgram>>(programParameters); } } // namespace gfx @@ -50,7 +69,7 @@ varying float v_gamma_scale; #ifndef HAS_UNIFORM_u_blur -uniform lowp float a_blur_t; +uniform lowp float u_blur_t; attribute lowp vec2 a_blur; varying lowp float blur; #else @@ -59,7 +78,7 @@ uniform lowp float u_blur; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -68,7 +87,7 @@ uniform lowp float u_opacity; #ifndef HAS_UNIFORM_u_offset -uniform lowp float a_offset_t; +uniform lowp float u_offset_t; attribute lowp vec2 a_offset; #else uniform lowp float u_offset; @@ -76,7 +95,7 @@ uniform lowp float u_offset; #ifndef HAS_UNIFORM_u_gapwidth -uniform lowp float a_gapwidth_t; +uniform lowp float u_gapwidth_t; attribute mediump vec2 a_gapwidth; #else uniform mediump float u_gapwidth; @@ -84,7 +103,7 @@ uniform mediump float u_gapwidth; #ifndef HAS_UNIFORM_u_width -uniform lowp float a_width_t; +uniform lowp float u_width_t; attribute mediump vec2 a_width; #else uniform mediump float u_width; @@ -92,7 +111,7 @@ uniform mediump float u_width; #ifndef HAS_UNIFORM_u_pattern_from -uniform lowp float a_pattern_from_t; +uniform lowp float u_pattern_from_t; attribute lowp vec4 a_pattern_from; varying lowp vec4 pattern_from; #else @@ -101,7 +120,7 @@ uniform lowp vec4 u_pattern_from; #ifndef HAS_UNIFORM_u_pattern_to -uniform lowp float a_pattern_to_t; +uniform lowp float u_pattern_to_t; attribute lowp vec4 a_pattern_to; varying lowp vec4 pattern_to; #else @@ -112,35 +131,35 @@ uniform lowp vec4 u_pattern_to; void main() { #ifndef HAS_UNIFORM_u_blur - blur = unpack_mix_vec2(a_blur, a_blur_t); + blur = unpack_mix_vec2(a_blur, u_blur_t); #else lowp float blur = u_blur; #endif #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif #ifndef HAS_UNIFORM_u_offset - lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); + lowp float offset = unpack_mix_vec2(a_offset, u_offset_t); #else lowp float offset = u_offset; #endif #ifndef HAS_UNIFORM_u_gapwidth - mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); + mediump float gapwidth = unpack_mix_vec2(a_gapwidth, u_gapwidth_t); #else mediump float gapwidth = u_gapwidth; #endif #ifndef HAS_UNIFORM_u_width - mediump float width = unpack_mix_vec2(a_width, a_width_t); + mediump float width = unpack_mix_vec2(a_width, u_width_t); #else mediump float width = u_width; #endif diff --git a/src/mbgl/programs/gl/line_sdf.cpp b/src/mbgl/programs/gl/line_sdf.cpp index 0886bfcdf0..a7b4e7e3b7 100644 --- a/src/mbgl/programs/gl/line_sdf.cpp +++ b/src/mbgl/programs/gl/line_sdf.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/line_sdf_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<LineSDFProgram> { + static constexpr const char* name = "line_sdf"; + static constexpr const uint8_t hash[8] = { 0x66, 0x20, 0x75, 0x4e, 0xbe, 0x02, 0x9e, 0x67 }; + static constexpr const auto vertexOffset = 43475; + static constexpr const auto fragmentOffset = 47089; +}; + +constexpr const char* ShaderSource<LineSDFProgram>::name; +constexpr const uint8_t ShaderSource<LineSDFProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<LineSDFProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<LineSDFProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "line_sdf", - programs::gl::shaderSource() + 43475, programs::gl::shaderSource() + 47089); + return std::make_unique<gl::Program<LineSDFProgram>>(programParameters); } } // namespace gfx @@ -55,7 +74,7 @@ varying float v_gamma_scale; #ifndef HAS_UNIFORM_u_color -uniform lowp float a_color_t; +uniform lowp float u_color_t; attribute highp vec4 a_color; varying highp vec4 color; #else @@ -64,7 +83,7 @@ uniform highp vec4 u_color; #ifndef HAS_UNIFORM_u_blur -uniform lowp float a_blur_t; +uniform lowp float u_blur_t; attribute lowp vec2 a_blur; varying lowp float blur; #else @@ -73,7 +92,7 @@ uniform lowp float u_blur; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -82,7 +101,7 @@ uniform lowp float u_opacity; #ifndef HAS_UNIFORM_u_gapwidth -uniform lowp float a_gapwidth_t; +uniform lowp float u_gapwidth_t; attribute mediump vec2 a_gapwidth; #else uniform mediump float u_gapwidth; @@ -90,7 +109,7 @@ uniform mediump float u_gapwidth; #ifndef HAS_UNIFORM_u_offset -uniform lowp float a_offset_t; +uniform lowp float u_offset_t; attribute lowp vec2 a_offset; #else uniform lowp float u_offset; @@ -98,7 +117,7 @@ uniform lowp float u_offset; #ifndef HAS_UNIFORM_u_width -uniform lowp float a_width_t; +uniform lowp float u_width_t; attribute mediump vec2 a_width; varying mediump float width; #else @@ -107,7 +126,7 @@ uniform mediump float u_width; #ifndef HAS_UNIFORM_u_floorwidth -uniform lowp float a_floorwidth_t; +uniform lowp float u_floorwidth_t; attribute lowp vec2 a_floorwidth; varying lowp float floorwidth; #else @@ -118,49 +137,49 @@ uniform lowp float u_floorwidth; void main() { #ifndef HAS_UNIFORM_u_color - color = unpack_mix_color(a_color, a_color_t); + color = unpack_mix_color(a_color, u_color_t); #else highp vec4 color = u_color; #endif #ifndef HAS_UNIFORM_u_blur - blur = unpack_mix_vec2(a_blur, a_blur_t); + blur = unpack_mix_vec2(a_blur, u_blur_t); #else lowp float blur = u_blur; #endif #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif #ifndef HAS_UNIFORM_u_gapwidth - mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); + mediump float gapwidth = unpack_mix_vec2(a_gapwidth, u_gapwidth_t); #else mediump float gapwidth = u_gapwidth; #endif #ifndef HAS_UNIFORM_u_offset - lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); + lowp float offset = unpack_mix_vec2(a_offset, u_offset_t); #else lowp float offset = u_offset; #endif #ifndef HAS_UNIFORM_u_width - width = unpack_mix_vec2(a_width, a_width_t); + width = unpack_mix_vec2(a_width, u_width_t); #else mediump float width = u_width; #endif #ifndef HAS_UNIFORM_u_floorwidth - floorwidth = unpack_mix_vec2(a_floorwidth, a_floorwidth_t); + floorwidth = unpack_mix_vec2(a_floorwidth, u_floorwidth_t); #else lowp float floorwidth = u_floorwidth; #endif diff --git a/src/mbgl/programs/gl/preludes.cpp b/src/mbgl/programs/gl/preludes.cpp deleted file mode 100644 index 6c895c0d36..0000000000 --- a/src/mbgl/programs/gl/preludes.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. - -#include <mbgl/programs/gl/preludes.hpp> -#include <mbgl/programs/gl/shader_source.hpp> - -namespace mbgl { -namespace programs { -namespace gl { - -const char* vertexShaderPrelude = programs::gl::shaderSource() + 0; -const char* fragmentShaderPrelude = programs::gl::shaderSource() + 1252; - -} // namespace gl -} // namespace programs -} // namespace mbgl diff --git a/src/mbgl/programs/gl/preludes.hpp b/src/mbgl/programs/gl/preludes.hpp index 6d86ee45c5..e796f1655b 100644 --- a/src/mbgl/programs/gl/preludes.hpp +++ b/src/mbgl/programs/gl/preludes.hpp @@ -2,12 +2,15 @@ #pragma once +#include <cstdint> + namespace mbgl { namespace programs { namespace gl { -extern const char* vertexShaderPrelude; -extern const char* fragmentShaderPrelude; +constexpr const uint8_t preludeHash[8] = { 0x24, 0x91, 0x82, 0x37, 0x02, 0xad, 0x98, 0x0a }; +constexpr const auto vertexPreludeOffset = 0; +constexpr const auto fragmentPreludeOffset = 1252; } // namespace gl } // namespace programs diff --git a/src/mbgl/programs/gl/raster.cpp b/src/mbgl/programs/gl/raster.cpp index 512dc81a30..1867a48f1c 100644 --- a/src/mbgl/programs/gl/raster.cpp +++ b/src/mbgl/programs/gl/raster.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/raster_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<RasterProgram> { + static constexpr const char* name = "raster"; + static constexpr const uint8_t hash[8] = { 0x40, 0x3d, 0x6c, 0xf4, 0xd0, 0x41, 0x51, 0x0e }; + static constexpr const auto vertexOffset = 48592; + static constexpr const auto fragmentOffset = 48941; +}; + +constexpr const char* ShaderSource<RasterProgram>::name; +constexpr const uint8_t ShaderSource<RasterProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<RasterProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<RasterProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "raster", - programs::gl::shaderSource() + 48592, programs::gl::shaderSource() + 48941); + return std::make_unique<gl::Program<RasterProgram>>(programParameters); } } // namespace gfx diff --git a/src/mbgl/programs/gl/shader_source.cpp b/src/mbgl/programs/gl/shader_source.cpp index 4a986403f7..00e70f749a 100644 --- a/src/mbgl/programs/gl/shader_source.cpp +++ b/src/mbgl/programs/gl/shader_source.cpp @@ -70,395 +70,395 @@ constexpr const uint8_t compressedShaderSource[] = { 0x3a, 0x0f, 0xf2, 0x3e, 0x9e, 0xa4, 0xf3, 0x18, 0x26, 0x4d, 0x2f, 0x9d, 0xa2, 0x4e, 0xec, 0xf6, 0x47, 0x8b, 0x3c, 0x9e, 0xf6, 0x52, 0xb3, 0x64, 0x82, 0x06, 0x4f, 0xa1, 0xc5, 0xff, 0x7d, 0x72, 0xd1, 0xfd, 0xfd, 0xcb, 0xd9, 0xe7, 0xaf, 0xdf, 0x7e, 0xed, 0x52, 0xd9, 0x7f, 0xc0, 0x6a, 0x80, - 0xc5, 0x91, 0x56, 0x10, 0x93, 0xac, 0x6e, 0x2e, 0xa1, 0x23, 0x04, 0xe0, 0xe1, 0xa0, 0xd9, 0x9c, - 0x7b, 0xa5, 0x2c, 0x92, 0x41, 0x57, 0x62, 0x95, 0x76, 0x65, 0xa9, 0x92, 0x16, 0x56, 0x03, 0x61, - 0xf3, 0x18, 0xad, 0xbe, 0x0b, 0x33, 0x65, 0x24, 0x4f, 0x21, 0x8d, 0xa9, 0x01, 0xb4, 0xc5, 0x04, - 0x82, 0x53, 0xa7, 0x28, 0x09, 0x35, 0x9a, 0xa9, 0x51, 0xa8, 0xc2, 0x30, 0x02, 0xd6, 0x50, 0x99, - 0x8c, 0xaf, 0x2c, 0xbd, 0x07, 0x39, 0x0a, 0x85, 0x38, 0x97, 0x92, 0x07, 0x99, 0x9c, 0x38, 0xa9, - 0x18, 0x4e, 0xd7, 0xe8, 0x92, 0xb2, 0x49, 0x7d, 0x6b, 0x48, 0xa2, 0x1c, 0x6e, 0xa6, 0x8a, 0x66, - 0x5a, 0x09, 0xe3, 0xea, 0x42, 0x91, 0x36, 0x31, 0x73, 0xec, 0xe4, 0x49, 0x30, 0x25, 0x14, 0x2e, - 0xf2, 0x79, 0xf6, 0xef, 0xb4, 0x8c, 0xf5, 0x64, 0x08, 0x3b, 0x07, 0xca, 0x50, 0x26, 0x46, 0x54, - 0xf2, 0xcb, 0xf8, 0x51, 0x07, 0x5c, 0x4f, 0xfb, 0xcd, 0xa8, 0x9f, 0x0f, 0x4b, 0x69, 0xc7, 0x10, - 0x65, 0x2c, 0x2a, 0xc3, 0x59, 0x18, 0x55, 0x01, 0x59, 0xc3, 0xae, 0x3a, 0xec, 0xfa, 0x36, 0x94, - 0x32, 0x8a, 0x0a, 0x63, 0xe5, 0x17, 0x15, 0xcc, 0xc4, 0x36, 0x1a, 0x44, 0x19, 0xf7, 0x14, 0x41, - 0x89, 0xbb, 0x40, 0x2c, 0x90, 0x87, 0x68, 0x81, 0xec, 0xc7, 0x79, 0x2c, 0xad, 0x8f, 0xf0, 0x0b, - 0xad, 0x91, 0xa5, 0xe2, 0xad, 0x47, 0x14, 0x5d, 0xdd, 0xc4, 0xa4, 0x32, 0xcc, 0xe7, 0xa2, 0xce, - 0x65, 0xe4, 0xe9, 0xd2, 0x2c, 0xda, 0x48, 0x66, 0x91, 0x3f, 0x91, 0x6e, 0x3b, 0x33, 0xa9, 0xe4, - 0x0b, 0x01, 0xc6, 0x2b, 0x34, 0x09, 0xa8, 0x68, 0x13, 0x19, 0x04, 0xff, 0x18, 0x6a, 0x84, 0x64, - 0x9f, 0x09, 0x23, 0x5e, 0x9b, 0x26, 0x71, 0xa2, 0x8d, 0xe4, 0x0a, 0xfd, 0x6b, 0xa8, 0x8c, 0xe6, - 0xf8, 0x92, 0x98, 0x31, 0x55, 0xc9, 0x11, 0x6c, 0x23, 0x2e, 0xe4, 0x0f, 0xd3, 0x88, 0xca, 0xf9, - 0xbe, 0x2e, 0x48, 0x4c, 0xe3, 0xab, 0x22, 0xdc, 0x5a, 0x14, 0xc8, 0x1f, 0x86, 0xae, 0x91, 0xb3, - 0x7d, 0x5d, 0x46, 0x58, 0xb8, 0x40, 0x45, 0x79, 0x8f, 0x09, 0xae, 0x7e, 0xda, 0xa9, 0x13, 0xe3, - 0xa7, 0xcf, 0x7e, 0xd3, 0x30, 0xea, 0x58, 0xad, 0xd3, 0x17, 0xfb, 0xac, 0x88, 0x42, 0x13, 0xe1, - 0x0a, 0x41, 0x5d, 0x24, 0x76, 0x0d, 0xb8, 0xbb, 0x3c, 0xf4, 0x4f, 0x43, 0x68, 0x8d, 0xbd, 0xd1, - 0xbc, 0x87, 0xf4, 0x26, 0xa2, 0xd3, 0x44, 0xa8, 0x2a, 0x3c, 0xac, 0x08, 0xd8, 0x6b, 0x35, 0x8f, - 0xdd, 0x10, 0x19, 0xe1, 0x8e, 0xae, 0x3d, 0x31, 0x15, 0xb9, 0x97, 0xcd, 0xa7, 0x48, 0x0f, 0x9a, - 0x31, 0x4b, 0x4a, 0x41, 0x45, 0x4b, 0xaa, 0x5a, 0x19, 0x2a, 0xa9, 0x15, 0xaa, 0x47, 0x94, 0x54, - 0xcf, 0x21, 0x93, 0xaf, 0x2e, 0xf7, 0x3b, 0x68, 0x90, 0xaa, 0x6e, 0x76, 0x57, 0x83, 0x7e, 0xa1, - 0x6e, 0xa8, 0xd9, 0x3c, 0xfb, 0x57, 0xda, 0xcb, 0xd3, 0x3e, 0x23, 0x5f, 0xb5, 0xe5, 0x14, 0x7a, - 0x88, 0x4d, 0x77, 0xbf, 0xda, 0x3d, 0x47, 0xaf, 0xb1, 0x79, 0x13, 0x94, 0x68, 0x86, 0xc8, 0xa2, - 0xb2, 0x5b, 0x9a, 0x1a, 0x29, 0xd4, 0xcd, 0x40, 0x9b, 0x57, 0x52, 0xac, 0xd8, 0x28, 0x4b, 0x4f, - 0x4b, 0x38, 0x9a, 0xcb, 0xd5, 0xa6, 0x4d, 0x2d, 0x53, 0x78, 0x0d, 0x54, 0x6e, 0x51, 0x83, 0x5c, - 0xfa, 0x26, 0xbc, 0xbb, 0x93, 0xd7, 0xc3, 0x69, 0x3e, 0x8a, 0xc7, 0xa3, 0x78, 0x81, 0xc5, 0x25, - 0x62, 0xd6, 0xe0, 0xd3, 0xe9, 0x1f, 0x67, 0x1f, 0x4f, 0xbb, 0xe7, 0x67, 0x7f, 0x9e, 0xfe, 0xd2, - 0xfd, 0x76, 0xf2, 0xdb, 0xd9, 0xd7, 0xc0, 0x58, 0x4b, 0x48, 0x16, 0x2c, 0x60, 0xfc, 0x43, 0x87, - 0xd6, 0xd7, 0x5c, 0xfa, 0xec, 0x17, 0x9a, 0x6c, 0x32, 0x6a, 0x97, 0x3a, 0xba, 0xac, 0x2b, 0xd9, - 0x63, 0xab, 0xdb, 0xbb, 0x51, 0x98, 0x1f, 0x59, 0xf3, 0xdd, 0x9d, 0xf2, 0xfa, 0x14, 0x4a, 0xe7, - 0x53, 0xaa, 0x8a, 0x4f, 0xa0, 0xdf, 0x51, 0xdd, 0xce, 0x36, 0x21, 0xaa, 0x68, 0x6a, 0x56, 0x6e, - 0xaf, 0xac, 0x75, 0x59, 0xf8, 0x78, 0xbd, 0x1e, 0x65, 0x67, 0xd2, 0xaa, 0x0a, 0xd1, 0x1a, 0x0e, - 0xdc, 0x5c, 0x93, 0x59, 0xc3, 0x5e, 0x5b, 0xe9, 0x20, 0x6b, 0x19, 0xe7, 0xde, 0x7a, 0x03, 0x66, - 0x0b, 0x24, 0xd4, 0x43, 0x82, 0x84, 0x49, 0xee, 0x71, 0x3a, 0x1d, 0x20, 0xca, 0xc8, 0x1f, 0x26, - 0x5f, 0xdd, 0xd0, 0x2a, 0xba, 0x29, 0x9e, 0xdb, 0x50, 0xcb, 0x44, 0x0b, 0x28, 0xce, 0x6f, 0x4c, - 0xe2, 0xa5, 0x43, 0x94, 0x66, 0x55, 0x2e, 0x2b, 0x23, 0xd5, 0xcd, 0xa3, 0xc5, 0x24, 0xcb, 0xf2, - 0xe1, 0x22, 0x4f, 0x67, 0x4e, 0xab, 0xd9, 0xf2, 0x75, 0x44, 0xbe, 0x4a, 0x20, 0xd1, 0x6f, 0x08, - 0x0e, 0xaa, 0x8b, 0x46, 0x72, 0x5f, 0xd6, 0xfe, 0x51, 0x43, 0x58, 0xda, 0xb5, 0x9f, 0xe0, 0x4f, - 0xed, 0x43, 0x4d, 0xc2, 0x5e, 0xc0, 0x0c, 0xd5, 0x69, 0xd8, 0x09, 0xc3, 0x9a, 0x17, 0x20, 0xcd, - 0x35, 0xc6, 0x5b, 0xe0, 0x71, 0x27, 0x99, 0xc7, 0xf4, 0x3e, 0x99, 0x63, 0x3c, 0x4d, 0x27, 0x94, - 0x34, 0xe8, 0x7b, 0x38, 0xce, 0x1e, 0x7b, 0x4b, 0xc4, 0xbe, 0xcb, 0x21, 0xc8, 0xb1, 0xae, 0xb0, - 0x37, 0x29, 0x9a, 0x4b, 0xb9, 0xd9, 0x1c, 0x26, 0x79, 0x66, 0x57, 0x44, 0x87, 0xe7, 0x6b, 0x4e, - 0x08, 0x52, 0x98, 0x66, 0x19, 0x97, 0x02, 0x26, 0x19, 0x05, 0xcc, 0x63, 0x7b, 0xc4, 0x36, 0x5b, - 0xc3, 0xcb, 0x1d, 0x9d, 0xac, 0x90, 0xd9, 0x5b, 0x69, 0x73, 0x8b, 0xb3, 0xf4, 0x11, 0xd2, 0xe1, - 0xa6, 0x0b, 0xc8, 0xa9, 0xb2, 0x93, 0x42, 0xeb, 0x08, 0xc9, 0x0e, 0xa6, 0xdc, 0x7b, 0xff, 0x3c, - 0xfd, 0xf6, 0x15, 0xab, 0x64, 0x78, 0xeb, 0x3a, 0x68, 0xbf, 0x69, 0xb6, 0x42, 0xbe, 0x31, 0xf7, - 0xf3, 0xc9, 0xef, 0x17, 0x17, 0xdd, 0x8f, 0x5f, 0x4f, 0x3f, 0xa3, 0x99, 0x75, 0xf8, 0xfe, 0xdd, - 0xfb, 0xa3, 0x4e, 0xe7, 0x5d, 0xeb, 0xa8, 0xd5, 0x3e, 0x3a, 0xec, 0xbc, 0x3d, 0xa8, 0xea, 0x45, - 0xa0, 0x9c, 0x41, 0xfe, 0x18, 0xec, 0x27, 0x92, 0xe1, 0x0b, 0x36, 0xd1, 0x0c, 0x4d, 0x99, 0x11, - 0xa2, 0xcd, 0x46, 0xdb, 0xbc, 0x44, 0x3d, 0xb8, 0x67, 0x81, 0x9e, 0x80, 0xc0, 0x23, 0xd8, 0xef, - 0x56, 0xb2, 0xd6, 0x08, 0xc2, 0x8b, 0x68, 0xf1, 0xbf, 0xf3, 0xdc, 0x69, 0xa0, 0x64, 0x6f, 0x9c, - 0x0d, 0x1c, 0x18, 0x8d, 0x80, 0x34, 0x30, 0x90, 0xc6, 0x38, 0x10, 0x03, 0xe1, 0xba, 0xc1, 0x21, - 0x1a, 0x22, 0x3e, 0xa4, 0xd1, 0x85, 0xa7, 0x57, 0x1c, 0x6a, 0xb2, 0x9f, 0xe9, 0xf1, 0x84, 0xe8, - 0x82, 0x0d, 0x46, 0x6c, 0xaf, 0x6c, 0x41, 0x26, 0xb9, 0x6e, 0x32, 0xd6, 0x29, 0x30, 0x11, 0x12, - 0x46, 0x49, 0x02, 0xfc, 0xb6, 0x4e, 0x2c, 0x3c, 0xd0, 0xd4, 0x36, 0x03, 0x89, 0xb9, 0x60, 0x61, - 0xfb, 0x8d, 0x19, 0xda, 0xaa, 0x36, 0xd1, 0xe6, 0x54, 0x61, 0x4c, 0x92, 0xdb, 0x8f, 0x1a, 0xa8, - 0x1b, 0x3d, 0x34, 0x66, 0xf8, 0xff, 0x7e, 0x96, 0x3b, 0x9c, 0x2e, 0x9f, 0xff, 0x62, 0xfc, 0x70, - 0x1d, 0x8f, 0x23, 0x82, 0xc6, 0x93, 0x9a, 0xe5, 0x09, 0xb2, 0xbd, 0x74, 0x39, 0x73, 0xfa, 0xda, - 0xaa, 0x84, 0x07, 0x0e, 0x15, 0x85, 0xdd, 0x23, 0xf6, 0xbf, 0xbb, 0x83, 0x7d, 0xe8, 0x9b, 0x6c, - 0x3e, 0xee, 0x57, 0xdd, 0xc9, 0xdd, 0x68, 0x49, 0xf2, 0x28, 0x72, 0x69, 0xeb, 0xb6, 0xb9, 0x8c, - 0x62, 0xf2, 0x97, 0x7e, 0xaf, 0x40, 0x6c, 0x35, 0x48, 0xda, 0x4a, 0xde, 0xec, 0x2c, 0xee, 0x1c, - 0x9a, 0x72, 0xc8, 0x92, 0x3c, 0x47, 0x29, 0xf6, 0x5d, 0xff, 0x35, 0x8d, 0xa0, 0x47, 0x45, 0x0c, - 0xbb, 0x6a, 0x18, 0xd8, 0x6d, 0xce, 0xa5, 0xcd, 0x37, 0x05, 0x4a, 0x54, 0xee, 0x63, 0x29, 0x91, - 0xfb, 0x30, 0xd7, 0xb4, 0x61, 0xbd, 0xd7, 0xc1, 0x82, 0x56, 0x15, 0xdd, 0xa1, 0x90, 0x18, 0x4f, - 0x7b, 0xc3, 0x6c, 0x6e, 0xce, 0x63, 0x93, 0xa9, 0x88, 0x69, 0x1c, 0xf7, 0x52, 0x03, 0x1f, 0x2c, - 0x86, 0xa3, 0xcb, 0x3c, 0xac, 0xc4, 0x49, 0xe5, 0x6b, 0xa0, 0xdd, 0x75, 0xc1, 0x46, 0x88, 0xce, - 0x1e, 0x46, 0x8a, 0x9e, 0x3c, 0xcd, 0xf2, 0xdf, 0x17, 0x90, 0xae, 0xed, 0x0b, 0x4b, 0x3e, 0xa7, - 0xf3, 0x0c, 0x4d, 0xb7, 0x02, 0x2b, 0x8a, 0xfe, 0x20, 0x9c, 0x28, 0xcf, 0x7b, 0x41, 0x15, 0x85, - 0x62, 0x54, 0x45, 0x2a, 0xd2, 0xe6, 0x8d, 0x5a, 0x2c, 0x1b, 0x8f, 0xf1, 0xd9, 0x9b, 0xee, 0x2c, - 0x9d, 0x2f, 0x66, 0x08, 0x6e, 0x74, 0x9d, 0x22, 0x56, 0x40, 0x53, 0x21, 0xea, 0x8d, 0x11, 0x47, - 0xa0, 0xa1, 0x3b, 0xae, 0x83, 0xcc, 0x70, 0x4a, 0x5a, 0x1e, 0x58, 0x6b, 0x77, 0xb1, 0x8a, 0x7b, - 0x04, 0xc3, 0xbf, 0x56, 0xef, 0x63, 0xa2, 0x42, 0xf7, 0xfc, 0x38, 0x7c, 0xb4, 0xeb, 0x74, 0x18, - 0xd7, 0xf8, 0x7b, 0xbc, 0x92, 0x56, 0x85, 0x6c, 0x58, 0x22, 0xc6, 0x2a, 0x78, 0x0a, 0xd3, 0x31, - 0x11, 0x89, 0x78, 0x0e, 0xdf, 0x67, 0x40, 0xa9, 0x36, 0x37, 0x9e, 0x0d, 0xe3, 0x08, 0xf5, 0x5f, - 0x68, 0x94, 0x72, 0xb8, 0xd1, 0xac, 0xe1, 0x1e, 0x06, 0xc6, 0x1e, 0x37, 0x56, 0x55, 0xed, 0xbf, - 0x6a, 0x30, 0x15, 0x4d, 0xfa, 0xaf, 0x54, 0x12, 0x4f, 0x57, 0x5a, 0xfa, 0x8e, 0x14, 0xa7, 0x24, - 0x19, 0xcb, 0x7b, 0x51, 0xb3, 0x1d, 0xde, 0xed, 0x64, 0x16, 0x3e, 0xab, 0xe9, 0xa6, 0xa5, 0x6b, - 0xdb, 0xca, 0xda, 0x22, 0x6d, 0x4e, 0x66, 0x4a, 0xca, 0x7e, 0xe6, 0x1a, 0x67, 0xae, 0x4c, 0xdf, - 0x2c, 0xee, 0xf7, 0x51, 0x07, 0x76, 0x2f, 0xe3, 0x5e, 0x9e, 0x81, 0x9f, 0xb5, 0x53, 0x98, 0xd8, - 0x9c, 0x7f, 0x0a, 0xd3, 0x59, 0x2d, 0xfc, 0x18, 0xb3, 0x9b, 0x8d, 0x7f, 0x14, 0x27, 0x0b, 0x21, - 0x60, 0x9a, 0x2b, 0x57, 0x52, 0x66, 0x05, 0x7d, 0x2a, 0x3d, 0xa1, 0xc6, 0x0f, 0xd1, 0x06, 0xfe, - 0xed, 0x52, 0xea, 0x25, 0xb5, 0x81, 0xaf, 0xfe, 0xd7, 0x08, 0x0a, 0x7b, 0xdf, 0x59, 0xdd, 0xcf, - 0x83, 0xeb, 0x75, 0xf1, 0x26, 0xa9, 0x16, 0x1b, 0x0b, 0xb7, 0xde, 0xb6, 0x52, 0xad, 0x47, 0xc5, - 0x59, 0x87, 0x1d, 0x71, 0x56, 0x08, 0xd6, 0x1c, 0x4a, 0x5a, 0x73, 0xdc, 0x52, 0xef, 0x93, 0xd0, - 0x85, 0x3d, 0x13, 0xce, 0xd0, 0xe0, 0x51, 0x6b, 0x23, 0x8b, 0xd5, 0x08, 0x1c, 0x18, 0x46, 0x51, - 0xb1, 0xe0, 0xd8, 0xa8, 0x94, 0x55, 0xc5, 0xf8, 0x07, 0x58, 0x2a, 0xed, 0x0f, 0x52, 0xcc, 0xb7, - 0x46, 0xd7, 0x51, 0xa9, 0x7f, 0xab, 0xa1, 0x6c, 0x5e, 0x42, 0x4f, 0x37, 0x74, 0xcc, 0x56, 0x27, - 0x13, 0xf1, 0x3e, 0xde, 0xed, 0xee, 0x30, 0xac, 0x61, 0xe3, 0x63, 0xed, 0xd1, 0xd7, 0x0d, 0xe9, - 0x7b, 0x69, 0x27, 0xa9, 0x9e, 0xd3, 0x81, 0xa0, 0x82, 0x81, 0xfa, 0xe4, 0x67, 0x36, 0x76, 0x70, - 0xac, 0xa1, 0x2a, 0x0f, 0x3f, 0xc9, 0xc6, 0xdf, 0x03, 0x6f, 0x9a, 0x3d, 0xf2, 0xc6, 0xcd, 0x46, - 0xbb, 0x27, 0x06, 0x5b, 0xf4, 0x41, 0x8e, 0x7f, 0x6e, 0x20, 0x2b, 0x8c, 0xfe, 0x06, 0x83, 0x55, - 0x6e, 0x1b, 0x9c, 0xab, 0x7c, 0x3c, 0x9a, 0x96, 0x1e, 0x95, 0x53, 0x40, 0xec, 0x32, 0x46, 0x01, - 0x33, 0xc9, 0x1a, 0x15, 0xa0, 0x8c, 0xab, 0x0a, 0x90, 0xaf, 0x48, 0xf6, 0xa8, 0x1d, 0xae, 0x7c, - 0x99, 0x64, 0x91, 0x02, 0xe0, 0x17, 0x06, 0xc3, 0x24, 0x9b, 0x34, 0x9c, 0x5b, 0xf5, 0xe6, 0x53, - 0xcb, 0x2a, 0xcc, 0xb3, 0x91, 0xa3, 0xea, 0xe6, 0x81, 0xa2, 0x71, 0xd7, 0x61, 0xd2, 0x04, 0xe0, - 0x15, 0x66, 0x5c, 0x6f, 0x15, 0x70, 0x6a, 0x9f, 0xef, 0x9c, 0x35, 0x1f, 0x8a, 0xbb, 0xd6, 0xb8, - 0xda, 0x2c, 0xf2, 0x4c, 0x69, 0xfb, 0x36, 0x6c, 0x72, 0x4f, 0x19, 0x29, 0x34, 0x45, 0xa1, 0xc6, - 0x22, 0xda, 0x1b, 0x5c, 0x0a, 0x66, 0x73, 0x64, 0x0f, 0xad, 0x98, 0x82, 0x48, 0x94, 0x77, 0x70, - 0x5b, 0x6a, 0x1b, 0xa0, 0xa0, 0x7c, 0x03, 0x16, 0x5d, 0x13, 0x94, 0xc9, 0xf6, 0x1c, 0x5c, 0x9c, - 0x09, 0xe1, 0xdd, 0x39, 0x78, 0x1f, 0xee, 0x06, 0x11, 0x3b, 0xbb, 0x81, 0x8d, 0x9b, 0xfb, 0xde, - 0x00, 0xaa, 0xbe, 0x0c, 0x3c, 0xfb, 0x23, 0xdd, 0xec, 0x1e, 0xc7, 0xe5, 0x3c, 0x9b, 0x98, 0xc9, - 0x94, 0x21, 0x8c, 0xb4, 0x1e, 0x69, 0x40, 0x2a, 0xc1, 0xf4, 0x22, 0xa8, 0x94, 0x6d, 0x22, 0x9a, - 0x0e, 0x8f, 0x0e, 0x57, 0x81, 0xf0, 0x3c, 0x2b, 0x27, 0x1b, 0x19, 0x3a, 0xeb, 0x88, 0xce, 0xb3, - 0x12, 0x92, 0x51, 0x66, 0x05, 0x82, 0x09, 0x54, 0xf5, 0xd5, 0xea, 0xa9, 0x8e, 0xe4, 0x2a, 0xc3, - 0x2d, 0x7f, 0x44, 0x71, 0xd7, 0x34, 0x48, 0xd2, 0x5e, 0xb4, 0x3a, 0x8a, 0xd1, 0xb6, 0x83, 0x25, - 0x7e, 0x46, 0x71, 0xb7, 0xd8, 0xc9, 0xc6, 0x0a, 0x11, 0xac, 0xb9, 0xab, 0xe5, 0x8b, 0xb4, 0x70, - 0x69, 0x2a, 0x92, 0x69, 0x82, 0x43, 0x27, 0x0a, 0x04, 0xdc, 0x9e, 0x52, 0x21, 0x6e, 0x6f, 0x42, - 0x1d, 0x47, 0x12, 0x89, 0x8a, 0x4c, 0x18, 0x94, 0x7c, 0x54, 0x9e, 0x3a, 0xc0, 0x40, 0xf0, 0x7c, - 0xc3, 0xfe, 0x38, 0x2a, 0x64, 0x9a, 0xcb, 0x50, 0xdc, 0xe7, 0x55, 0x73, 0xd8, 0x59, 0x18, 0x20, - 0xe1, 0x82, 0xfa, 0x94, 0x48, 0x0e, 0x3b, 0xde, 0x92, 0x67, 0x6a, 0xfa, 0x4d, 0x58, 0x6d, 0x79, - 0x07, 0x5a, 0x91, 0x30, 0x9f, 0x8d, 0xe3, 0x15, 0xbd, 0x21, 0x48, 0xb6, 0x82, 0x1d, 0xb9, 0x0b, - 0x9a, 0xcb, 0x86, 0xdc, 0x67, 0xcd, 0xa5, 0x1b, 0x08, 0xf2, 0x7d, 0x15, 0x74, 0xa5, 0x82, 0xae, - 0x64, 0x50, 0x53, 0x7d, 0x49, 0xb1, 0xbe, 0x44, 0xad, 0x2f, 0x29, 0xa9, 0x2f, 0x51, 0xeb, 0x4b, - 0x0a, 0xf5, 0xdd, 0xf3, 0x22, 0x25, 0xef, 0x70, 0x4f, 0xed, 0x24, 0x9f, 0x8f, 0xd1, 0x43, 0xdd, - 0x9c, 0xa4, 0x03, 0xa8, 0xd6, 0x93, 0x58, 0xea, 0xd9, 0x42, 0x21, 0x5b, 0x73, 0xdb, 0xd1, 0xbe, - 0x0f, 0xc9, 0x56, 0x87, 0xcb, 0xb8, 0x9f, 0x3e, 0xea, 0x92, 0xb7, 0xbb, 0x55, 0x6b, 0xd7, 0xcb, - 0xcd, 0x63, 0xae, 0x15, 0x8f, 0x71, 0xec, 0x50, 0xe9, 0xac, 0x6d, 0x04, 0x7a, 0x69, 0x6f, 0xbc, - 0x38, 0x81, 0xbd, 0xd9, 0xa5, 0x5c, 0xcb, 0x95, 0xdc, 0x27, 0xba, 0x90, 0x6b, 0xb9, 0x8e, 0xfb, - 0x60, 0x97, 0x71, 0x1f, 0xd9, 0xa8, 0x30, 0x5d, 0xef, 0x05, 0x41, 0x44, 0x3d, 0xff, 0xde, 0x0e, - 0xe3, 0x18, 0x3c, 0x0f, 0x4b, 0x62, 0x6f, 0x36, 0xec, 0xcd, 0x86, 0xbd, 0xd9, 0xb0, 0x37, 0x1b, - 0x2c, 0x66, 0xc3, 0x3f, 0xb3, 0x6c, 0x72, 0x7f, 0xd3, 0xe1, 0xb5, 0x5b, 0x05, 0x3b, 0x89, 0xc1, - 0x52, 0x6a, 0x3a, 0xf0, 0x71, 0xda, 0x81, 0xf9, 0x50, 0xa8, 0x6b, 0xbd, 0x35, 0xa0, 0xe8, 0xfc, - 0x0f, 0x11, 0xe4, 0x64, 0xaf, 0xfa, 0xef, 0x55, 0xff, 0xbd, 0xea, 0xff, 0xba, 0x54, 0xff, 0x8a, - 0x8a, 0xfa, 0x6e, 0x54, 0xf4, 0x43, 0x94, 0x3a, 0x86, 0xb3, 0xe8, 0x6a, 0x6c, 0x34, 0x36, 0xa5, - 0x78, 0xb6, 0xbc, 0x7f, 0xab, 0xc8, 0x12, 0x9c, 0x2b, 0x0e, 0xe7, 0xeb, 0x92, 0xf0, 0x3a, 0x9d, - 0xe7, 0x23, 0x24, 0x61, 0xbb, 0x03, 0x38, 0x46, 0x93, 0x4e, 0xf3, 0x70, 0xfd, 0xf1, 0x48, 0x50, - 0xfd, 0xa6, 0x08, 0x09, 0x2a, 0x95, 0x2a, 0x5b, 0xc1, 0x47, 0x48, 0x2e, 0xb2, 0xdd, 0x1d, 0xf3, - 0xd5, 0xd9, 0xd8, 0x2c, 0xf2, 0x62, 0x9c, 0x63, 0xbf, 0x9b, 0x04, 0xb9, 0xe5, 0x77, 0x14, 0x18, - 0x44, 0x89, 0xf4, 0x1a, 0x96, 0x5c, 0x8e, 0x1a, 0xae, 0xb9, 0x1c, 0x35, 0xac, 0x70, 0x4d, 0x62, - 0x58, 0xe5, 0x4e, 0xcc, 0x7d, 0x8f, 0xd8, 0x54, 0x3f, 0x2b, 0x51, 0x45, 0x8d, 0xc6, 0xe3, 0x21, - 0xb7, 0x02, 0x12, 0x4c, 0x31, 0x38, 0x50, 0xb2, 0xcf, 0x06, 0xc9, 0x78, 0x33, 0x88, 0x14, 0xdc, - 0x60, 0x18, 0xe4, 0xc2, 0x43, 0xdb, 0xad, 0xa4, 0x21, 0xbb, 0x95, 0x34, 0x2c, 0xbb, 0x95, 0xc4, - 0x8a, 0x6f, 0x32, 0x02, 0xc5, 0xb3, 0x1b, 0x0f, 0x78, 0x4c, 0x07, 0x4f, 0x4c, 0x32, 0x43, 0x22, - 0x69, 0xaa, 0x20, 0xc1, 0x7c, 0x1b, 0xe2, 0x8e, 0x82, 0x2b, 0x9a, 0xe0, 0x1d, 0x80, 0x0f, 0x37, - 0xa4, 0xf4, 0xb3, 0x44, 0xf2, 0xc9, 0x3c, 0x0b, 0x24, 0xa8, 0x25, 0xc1, 0xd1, 0x5c, 0xe2, 0x0b, - 0x4c, 0x6b, 0xf5, 0xbc, 0x1c, 0x1f, 0x15, 0x6c, 0xd5, 0x7e, 0xa2, 0x5d, 0x53, 0xfb, 0x80, 0xc7, - 0x07, 0xb4, 0x3f, 0xe9, 0x02, 0xe7, 0x35, 0x0e, 0x45, 0x8b, 0x7f, 0x36, 0xe7, 0x5e, 0xab, 0xd9, - 0x69, 0x77, 0xde, 0xd4, 0xc9, 0xe7, 0x00, 0x7d, 0xbe, 0x6d, 0x1f, 0x77, 0xe8, 0x67, 0x82, 0x3e, - 0x5b, 0x6f, 0x3b, 0x9d, 0x90, 0x4e, 0x6f, 0xf5, 0xd0, 0x22, 0x3f, 0x07, 0x4b, 0x18, 0x75, 0x92, - 0x80, 0x18, 0xc1, 0x62, 0x87, 0xc3, 0x1d, 0xfa, 0xe2, 0x1f, 0x0c, 0x8a, 0xd1, 0xd4, 0x23, 0x19, - 0x98, 0xbb, 0x5c, 0xe6, 0x70, 0x38, 0x34, 0x9b, 0xa2, 0xbe, 0x23, 0x07, 0x7a, 0xe1, 0xba, 0x0e, - 0x69, 0x7f, 0xd0, 0x7e, 0x73, 0xf8, 0xee, 0x08, 0x02, 0xc0, 0x72, 0xa1, 0xe7, 0x8a, 0xea, 0xe5, - 0x92, 0x20, 0xb6, 0x41, 0xd8, 0x36, 0x74, 0x01, 0xe8, 0x42, 0x54, 0x53, 0x92, 0x25, 0x3a, 0xa1, - 0x5e, 0x84, 0x02, 0x8c, 0xbe, 0x84, 0x91, 0x84, 0x84, 0xa0, 0xc3, 0xb0, 0xaa, 0xfd, 0x10, 0xc1, - 0xdd, 0x8e, 0xda, 0x7f, 0x24, 0x08, 0x2f, 0x62, 0x35, 0x16, 0x64, 0xaa, 0x5b, 0x77, 0x0c, 0xa9, - 0x1e, 0x69, 0x9e, 0x93, 0xd7, 0x31, 0x1b, 0x78, 0xb3, 0xec, 0xc6, 0x21, 0xe3, 0x15, 0xb4, 0x8f, - 0x5b, 0xf4, 0x24, 0xa8, 0x0f, 0x2d, 0x41, 0x83, 0x81, 0x3e, 0xde, 0xbf, 0xf3, 0xcd, 0x2d, 0x02, - 0x5a, 0x71, 0xc8, 0xdd, 0x2e, 0x1d, 0xcc, 0x3a, 0xed, 0x39, 0x36, 0xb6, 0x32, 0x95, 0xf2, 0x72, - 0xd2, 0x9c, 0x53, 0xf4, 0x50, 0xd7, 0xa1, 0x8c, 0x9d, 0x66, 0xbb, 0x74, 0x60, 0x29, 0xe2, 0x81, - 0x8a, 0x78, 0x60, 0x47, 0x3c, 0x28, 0x47, 0x3c, 0xd0, 0x10, 0x27, 0x2a, 0xe2, 0xc4, 0x8e, 0x38, - 0x29, 0x47, 0x9c, 0x50, 0xc4, 0xd2, 0x2d, 0x06, 0x65, 0x5d, 0x2a, 0xb9, 0x5d, 0x2b, 0xad, 0x5c, - 0xcf, 0xd6, 0xe3, 0xa6, 0x2e, 0x35, 0xec, 0x54, 0xad, 0xd1, 0x1f, 0xb7, 0x7e, 0xa1, 0x7f, 0x44, - 0x2d, 0xe3, 0x1e, 0x3a, 0x44, 0xf5, 0xed, 0x17, 0x18, 0x55, 0x5a, 0xef, 0xe0, 0x01, 0x14, 0x0e, - 0x25, 0xb8, 0x1d, 0x2c, 0x63, 0xa6, 0x10, 0x1f, 0x06, 0x3d, 0x44, 0x0d, 0xf1, 0xf1, 0xe0, 0x6a, - 0x88, 0x4c, 0xd6, 0x50, 0xbd, 0xa2, 0x2d, 0x15, 0x35, 0xeb, 0x27, 0x0a, 0x69, 0x95, 0x16, 0xc7, - 0xbd, 0x37, 0xf3, 0x29, 0xbc, 0x99, 0x98, 0x4b, 0x37, 0x52, 0xbd, 0x34, 0x9e, 0xdc, 0x4c, 0xf3, - 0xda, 0x5c, 0xdb, 0x2a, 0x70, 0x5a, 0xb4, 0x0d, 0x3f, 0xed, 0xdd, 0xa5, 0x2f, 0xe7, 0x94, 0x45, - 0x99, 0x0a, 0x4b, 0x6f, 0x90, 0xf4, 0x07, 0x29, 0xbf, 0xb3, 0x25, 0x83, 0xbc, 0x7e, 0x3f, 0xeb, - 0x43, 0xe8, 0xf0, 0x24, 0xe7, 0x36, 0xb2, 0xe8, 0xea, 0x6b, 0x75, 0xfc, 0x5b, 0x7e, 0xcc, 0x05, - 0xbc, 0x34, 0x0c, 0x77, 0x04, 0x7b, 0x90, 0xb5, 0xbf, 0xff, 0xbd, 0xc6, 0x34, 0xd5, 0x08, 0x14, - 0x55, 0x29, 0xe1, 0x16, 0x41, 0x10, 0x25, 0xfa, 0xe0, 0x27, 0xb2, 0x2e, 0x1f, 0x7c, 0x20, 0x2f, - 0x3c, 0xc8, 0xe3, 0xe9, 0xdf, 0x7a, 0x9a, 0x92, 0xb1, 0x93, 0x23, 0x27, 0xbb, 0x39, 0x70, 0x42, - 0x6b, 0x61, 0xaa, 0x83, 0xc5, 0x98, 0xa9, 0x68, 0x8d, 0x1c, 0x3e, 0x84, 0x35, 0x02, 0x57, 0x16, - 0x5f, 0x8b, 0x09, 0xc2, 0xba, 0xb5, 0x39, 0x1f, 0x70, 0xad, 0xde, 0xa6, 0xcd, 0x63, 0xcc, 0x38, - 0xac, 0x1c, 0x34, 0xc5, 0xa7, 0xbf, 0x0e, 0xdd, 0x82, 0x5e, 0x4f, 0xf3, 0xda, 0xe4, 0x69, 0x91, - 0xdd, 0xbb, 0xf9, 0xb7, 0xd1, 0x3a, 0x1f, 0x57, 0x7d, 0xdc, 0x95, 0x0e, 0xf8, 0xba, 0xf7, 0x15, - 0xf0, 0x40, 0xad, 0xd7, 0xa5, 0xac, 0xa3, 0x50, 0x4d, 0x2f, 0xda, 0xef, 0x46, 0xec, 0x77, 0x23, - 0xb6, 0xde, 0x8d, 0xa0, 0x8f, 0x03, 0x2d, 0xe9, 0x73, 0x3d, 0xf6, 0x0d, 0x89, 0xc2, 0xbe, 0x05, - 0x2d, 0xe1, 0x69, 0xf2, 0x6a, 0x1f, 0x8e, 0xc6, 0x78, 0x0c, 0xb4, 0x6a, 0xbc, 0x19, 0xa5, 0x9f, - 0x6c, 0x41, 0x67, 0x1e, 0x2a, 0x60, 0x4c, 0xa5, 0x2e, 0xef, 0x8f, 0x26, 0xb0, 0x0c, 0x67, 0xd3, - 0xb0, 0x5a, 0x64, 0x0b, 0x4a, 0xf4, 0x43, 0x8c, 0x89, 0x1c, 0xd6, 0x81, 0x04, 0xbc, 0x9a, 0x2d, - 0x46, 0x63, 0x04, 0x0b, 0xc1, 0xcc, 0x64, 0xca, 0xe8, 0xc5, 0x71, 0x6c, 0x64, 0x38, 0x52, 0x06, - 0xd2, 0xc9, 0x41, 0x1b, 0x0e, 0x94, 0x24, 0x76, 0x16, 0x58, 0x21, 0x35, 0x78, 0xd7, 0x7e, 0x8f, - 0xa3, 0x77, 0x61, 0x24, 0x75, 0x5a, 0x51, 0xc9, 0xab, 0x4a, 0xda, 0xcb, 0x71, 0x4a, 0xe8, 0xaa, - 0x2a, 0xba, 0x80, 0xbd, 0x9b, 0x75, 0xd6, 0xb9, 0xcd, 0x90, 0x70, 0x2e, 0x3c, 0xaf, 0x12, 0x2f, - 0x71, 0x3a, 0xf9, 0x46, 0xca, 0xec, 0xe9, 0x38, 0xbd, 0x06, 0xfd, 0x73, 0xea, 0xd0, 0x48, 0xcf, - 0x48, 0x08, 0xf8, 0x74, 0xd9, 0x19, 0xc5, 0x0b, 0x16, 0x52, 0x03, 0x87, 0xda, 0x2d, 0xf2, 0x15, - 0x91, 0x60, 0x1e, 0x0e, 0x10, 0xc7, 0x1f, 0xa0, 0xc2, 0x81, 0x20, 0xe7, 0x75, 0xfc, 0x67, 0x40, - 0x1f, 0xaf, 0xc2, 0x1f, 0x09, 0xf9, 0x20, 0xff, 0xba, 0x01, 0xd2, 0xf6, 0x91, 0x6a, 0x56, 0x78, - 0x8f, 0xa5, 0x7c, 0xb0, 0xb0, 0xa6, 0x2f, 0x11, 0x0d, 0x7d, 0x52, 0xc7, 0x96, 0x42, 0x83, 0x16, - 0x44, 0xa6, 0x0c, 0xff, 0xb9, 0xc2, 0xaa, 0x2f, 0x53, 0x9b, 0x13, 0x6b, 0xd9, 0x96, 0xad, 0x48, - 0xcf, 0x5a, 0x64, 0x6d, 0x6d, 0xfd, 0x2a, 0x94, 0xb6, 0x94, 0x22, 0xa9, 0xa1, 0x88, 0x9c, 0x7f, - 0x59, 0x81, 0x1a, 0x15, 0xe3, 0xa0, 0x0a, 0x11, 0x66, 0xfa, 0x87, 0x25, 0xbd, 0x65, 0x2e, 0x31, - 0xaa, 0x40, 0x9e, 0xb9, 0x64, 0xba, 0x8c, 0x07, 0x83, 0x14, 0xc7, 0xdd, 0x80, 0x19, 0x0d, 0x2c, - 0x5a, 0xfb, 0x47, 0xad, 0x83, 0x0d, 0xd0, 0x56, 0xf3, 0x08, 0x59, 0x9f, 0x3c, 0xf1, 0xa8, 0x79, - 0x8c, 0x13, 0x0f, 0x8f, 0x51, 0x2a, 0xfa, 0x43, 0xcd, 0xec, 0x74, 0x3e, 0xba, 0xa6, 0xd6, 0x75, - 0xaf, 0x7e, 0x89, 0xfe, 0x1b, 0xb9, 0x0d, 0x27, 0xae, 0xf7, 0xd1, 0x7f, 0x03, 0xd7, 0x77, 0x06, - 0xf5, 0x21, 0xfa, 0x8f, 0xa4, 0x25, 0xe8, 0xbf, 0x9e, 0xeb, 0x06, 0x35, 0xb0, 0x2b, 0x50, 0x1d, - 0xbe, 0x43, 0x90, 0x37, 0xf8, 0xf4, 0x80, 0x38, 0x13, 0x82, 0xa0, 0x7a, 0xfb, 0x7d, 0x13, 0xb1, - 0x6c, 0xa7, 0x41, 0xc0, 0xf4, 0x50, 0x5c, 0xd8, 0x96, 0xc0, 0xc2, 0x07, 0x13, 0xd1, 0x5c, 0xc2, - 0x5d, 0x00, 0x88, 0xf5, 0xe2, 0x93, 0xef, 0x15, 0xff, 0x66, 0xf1, 0xd7, 0x84, 0x39, 0xf6, 0x08, - 0x2b, 0xdf, 0x13, 0x49, 0x5b, 0x22, 0x1c, 0x4d, 0xb2, 0xb1, 0x7c, 0xc1, 0x5b, 0x2f, 0xe1, 0xc6, - 0xa8, 0xc2, 0x78, 0x2a, 0xad, 0x8d, 0x2c, 0x1d, 0x2b, 0xb4, 0xfa, 0x2e, 0xc3, 0x30, 0xee, 0x67, - 0x37, 0x7a, 0x2a, 0x08, 0x5d, 0x23, 0x78, 0xdc, 0x83, 0x88, 0x30, 0x22, 0x08, 0xe0, 0xf9, 0x59, - 0xed, 0xb0, 0xd9, 0x3e, 0x6a, 0x1f, 0xbf, 0xef, 0xbc, 0x39, 0x3e, 0x3c, 0x7e, 0xf7, 0xfe, 0xed, - 0xfb, 0xc3, 0x03, 0x43, 0x80, 0x21, 0x30, 0xef, 0xad, 0xcb, 0xac, 0xcc, 0x91, 0x0e, 0x79, 0xf0, - 0x0f, 0x99, 0x9d, 0x10, 0xdf, 0xd1, 0x95, 0x03, 0x3c, 0xe2, 0x15, 0xe3, 0x33, 0x09, 0xc8, 0xd3, - 0xcb, 0x16, 0x38, 0xc6, 0x6c, 0x3c, 0x5d, 0x38, 0x8e, 0x68, 0xf2, 0x5f, 0xad, 0xef, 0x0d, 0xe9, - 0xab, 0xfd, 0xdd, 0xf5, 0xb0, 0x25, 0x4d, 0xd5, 0x0a, 0xb7, 0xae, 0x66, 0x72, 0xcc, 0xe3, 0x6c, - 0x96, 0x46, 0x48, 0xe2, 0x4e, 0x11, 0x74, 0xe7, 0xd8, 0xa3, 0x47, 0xc5, 0x31, 0x45, 0x6e, 0x20, - 0xd5, 0xcb, 0xcf, 0x89, 0xe3, 0xd0, 0x37, 0x11, 0xe5, 0x5f, 0x62, 0xc3, 0xa3, 0x49, 0x86, 0x31, - 0x50, 0x26, 0xf6, 0x1b, 0x34, 0xd7, 0x45, 0xd3, 0xee, 0xfc, 0x0c, 0xdf, 0x77, 0x61, 0x79, 0xdc, - 0x57, 0x04, 0x5e, 0x9e, 0x0f, 0x72, 0x1b, 0xb9, 0x2d, 0x1e, 0xd1, 0xf1, 0xe2, 0xfe, 0xc0, 0xf8, - 0x76, 0x34, 0xb9, 0xc2, 0xa1, 0x8f, 0x49, 0xfa, 0xaa, 0x7e, 0x7e, 0x16, 0x4a, 0xe6, 0x4e, 0xbb, - 0xf9, 0xee, 0xed, 0x71, 0x43, 0xc4, 0x39, 0x6c, 0x37, 0xdf, 0x1e, 0xd3, 0x7c, 0x34, 0x49, 0xc9, - 0x7b, 0xa5, 0x10, 0x4f, 0x89, 0x97, 0x22, 0x81, 0x2e, 0x2f, 0x70, 0xd3, 0x79, 0x31, 0xdc, 0x14, - 0x90, 0x17, 0x68, 0x1c, 0xd0, 0x64, 0xc7, 0x5e, 0x6b, 0xdc, 0x3b, 0x64, 0x24, 0x02, 0x91, 0xca, - 0x90, 0x92, 0x0c, 0xd7, 0x63, 0xdf, 0x10, 0x33, 0x18, 0x0a, 0x30, 0xb2, 0x31, 0xc3, 0xe0, 0xf1, - 0x92, 0x2a, 0x64, 0x9b, 0xcc, 0x38, 0x93, 0x6e, 0x46, 0xe3, 0x81, 0x22, 0x29, 0xa0, 0x78, 0x91, - 0x5f, 0xd4, 0xb3, 0x21, 0x9a, 0xd5, 0x29, 0x3a, 0x77, 0x80, 0x85, 0x49, 0x44, 0x19, 0xd0, 0xf1, - 0x1d, 0x32, 0x36, 0x75, 0xda, 0x5f, 0x6e, 0x70, 0x7e, 0x86, 0x65, 0x89, 0xe0, 0x26, 0x12, 0xa2, - 0x1a, 0x0a, 0xd1, 0x9a, 0xc9, 0xcb, 0x60, 0x64, 0x26, 0xf8, 0x12, 0xf3, 0xfb, 0x18, 0x08, 0xa9, - 0x2a, 0x88, 0x93, 0x65, 0xe2, 0xcb, 0x89, 0x52, 0xe4, 0x90, 0xdc, 0x42, 0xc2, 0x8a, 0x52, 0xc5, - 0xcd, 0xd8, 0xad, 0x4b, 0x9f, 0xf7, 0x13, 0x6e, 0x7c, 0x4a, 0x9e, 0x7c, 0xf9, 0xed, 0xec, 0xe4, - 0x97, 0xb3, 0x93, 0x8b, 0xb3, 0x2f, 0x3f, 0xd7, 0x2c, 0x0f, 0x04, 0x20, 0x82, 0x39, 0x3c, 0x6e, - 0x19, 0x0e, 0xfa, 0x7c, 0xfc, 0xee, 0xed, 0x61, 0xab, 0xfd, 0xe6, 0xa0, 0xb0, 0xc3, 0x07, 0x56, - 0x13, 0x71, 0x58, 0x15, 0x77, 0xff, 0x70, 0x90, 0xf4, 0x72, 0x05, 0xb7, 0x18, 0xda, 0x17, 0xc2, - 0x45, 0x69, 0xd2, 0x09, 0xb5, 0x50, 0x7f, 0xd7, 0x50, 0x13, 0x75, 0x94, 0x02, 0x2d, 0x15, 0xc7, - 0x02, 0xea, 0x14, 0x22, 0x45, 0x0d, 0xe2, 0xc9, 0x24, 0x66, 0xa1, 0x9f, 0x0c, 0x01, 0x53, 0xc1, - 0x9a, 0x9a, 0xa6, 0x8b, 0xec, 0x32, 0x9e, 0xbf, 0xb8, 0x30, 0x3a, 0xfb, 0xa7, 0xbe, 0xb6, 0x38, - 0x66, 0x3b, 0x88, 0x67, 0x25, 0x4f, 0x65, 0xb1, 0xdc, 0xb2, 0xb8, 0xd5, 0x0c, 0x66, 0x5d, 0xe4, - 0x6a, 0x19, 0xae, 0xac, 0xcb, 0xf0, 0xeb, 0xb2, 0x96, 0x1e, 0xc3, 0x79, 0xf6, 0x0e, 0xc3, 0xd9, - 0xe5, 0x9d, 0xc2, 0x41, 0x4a, 0x48, 0x28, 0xe9, 0x90, 0xb5, 0xbd, 0x51, 0xa9, 0x2b, 0xd4, 0x7e, - 0x78, 0x7e, 0x21, 0x97, 0x5e, 0xfb, 0x83, 0x55, 0x9c, 0xe9, 0xd5, 0x81, 0x61, 0xc9, 0x06, 0x42, - 0x58, 0x96, 0x2f, 0xcf, 0x09, 0x4b, 0x08, 0x6f, 0x81, 0x66, 0x43, 0x9e, 0x97, 0x5b, 0x44, 0x5e, - 0x7c, 0x36, 0xf4, 0x08, 0xce, 0xf0, 0xc5, 0x5c, 0x30, 0xf6, 0x07, 0x2d, 0xbd, 0x09, 0xbb, 0xab, - 0x6d, 0xb0, 0xf5, 0x03, 0xeb, 0x84, 0xf2, 0x1e, 0x60, 0xcd, 0xd7, 0xf8, 0x5c, 0x09, 0x2f, 0x1a, - 0xc5, 0xec, 0xc5, 0x88, 0x46, 0xbb, 0xf3, 0x0e, 0xa9, 0xf7, 0x6c, 0x8a, 0xf1, 0xed, 0x94, 0x88, - 0x04, 0x36, 0x27, 0xef, 0x41, 0xe0, 0xa0, 0x95, 0xa0, 0xa8, 0x84, 0xd2, 0x12, 0x15, 0xf1, 0x58, - 0xe2, 0x04, 0x08, 0x5c, 0x01, 0x6e, 0x9d, 0x7e, 0xdd, 0x78, 0x6f, 0x8e, 0x68, 0x3c, 0x74, 0xe1, - 0x61, 0x95, 0x17, 0x6d, 0xf0, 0xdd, 0x2a, 0xb3, 0x97, 0x6f, 0x08, 0x4b, 0x30, 0xe0, 0xbf, 0xa5, - 0xbf, 0xe9, 0x36, 0x64, 0xc8, 0xc7, 0x97, 0xfd, 0x00, 0xbd, 0x81, 0x19, 0xbb, 0xf1, 0xf8, 0x92, - 0x64, 0x8a, 0x1c, 0x3a, 0x1a, 0x40, 0xbc, 0x47, 0x07, 0x84, 0x69, 0xb5, 0x90, 0xce, 0xb0, 0xd4, - 0x1d, 0xf6, 0x8b, 0xeb, 0xc1, 0x8a, 0xce, 0x02, 0x56, 0x2a, 0x57, 0xee, 0xb2, 0xab, 0x5c, 0x29, - 0xcb, 0xeb, 0xf5, 0x8a, 0x58, 0x3a, 0xf8, 0xc5, 0x0a, 0x50, 0x8c, 0xea, 0x8e, 0xa0, 0x8f, 0xea, - 0xe6, 0xe4, 0x39, 0x0b, 0xb9, 0x22, 0x57, 0xed, 0x14, 0x7c, 0x49, 0x94, 0x54, 0xe7, 0x89, 0xd8, - 0x99, 0x44, 0x83, 0xd0, 0xe4, 0x1a, 0x56, 0xa4, 0xa5, 0x01, 0xd4, 0xf2, 0x73, 0xe2, 0xbe, 0x44, - 0x0a, 0xe9, 0x95, 0x56, 0x07, 0xe9, 0x95, 0x4e, 0x44, 0xfe, 0xea, 0xd5, 0x78, 0x6c, 0x53, 0x10, - 0x29, 0xd3, 0x39, 0x04, 0xb2, 0x6e, 0x5c, 0xf9, 0x57, 0xf0, 0x6a, 0xbb, 0xf6, 0xa4, 0x17, 0x63, - 0x2c, 0xd5, 0xb6, 0x04, 0xfa, 0x03, 0xaa, 0x5c, 0xb1, 0x3d, 0xd0, 0xb2, 0x33, 0xa6, 0xe2, 0x85, - 0xf3, 0x8e, 0x52, 0x0c, 0xf7, 0x5f, 0xa1, 0x32, 0x63, 0xbc, 0x49, 0xfc, 0xa6, 0x16, 0xea, 0x32, - 0x39, 0x18, 0x28, 0xbb, 0x67, 0x4b, 0x6e, 0xcb, 0x5a, 0x4b, 0x99, 0x8a, 0x14, 0x2a, 0x2d, 0x84, - 0x0e, 0xf0, 0x4c, 0x7a, 0x22, 0xd8, 0xd2, 0x92, 0xba, 0x17, 0xad, 0xa7, 0x31, 0x58, 0x43, 0x50, - 0xc8, 0xd4, 0x4a, 0xe2, 0x20, 0x21, 0x4c, 0xe1, 0x63, 0x2e, 0x7e, 0xba, 0xf0, 0x78, 0x2f, 0xe8, - 0xbd, 0xaa, 0x72, 0x15, 0xdd, 0xac, 0xce, 0x1b, 0x15, 0xf7, 0xc7, 0x0d, 0xe1, 0xb7, 0x9b, 0x97, - 0x93, 0x4c, 0x57, 0xd0, 0x49, 0xdb, 0x5d, 0x8f, 0xf5, 0x4d, 0x73, 0x11, 0x0a, 0x12, 0x3a, 0x11, - 0x7e, 0xf7, 0xa7, 0x6e, 0xb6, 0xdd, 0xa0, 0x90, 0xdc, 0x47, 0xf2, 0xc5, 0x75, 0x62, 0x97, 0x4e, - 0x50, 0x7f, 0x41, 0x75, 0x0d, 0x87, 0xa3, 0xcf, 0x1b, 0x18, 0xb1, 0xeb, 0x8b, 0x0a, 0x71, 0xe4, - 0x54, 0x37, 0xc0, 0xe9, 0x16, 0xe3, 0xf5, 0x11, 0x42, 0x65, 0x71, 0xab, 0xf3, 0xd7, 0x93, 0x3f, - 0xbb, 0xbf, 0x9c, 0x7d, 0x39, 0xed, 0x7e, 0x3a, 0xbb, 0xf8, 0xed, 0xe4, 0xcb, 0xc7, 0xd3, 0xda, - 0x61, 0xe7, 0xed, 0x9b, 0xb7, 0x92, 0x5d, 0xba, 0xb7, 0x63, 0xab, 0xdb, 0xb1, 0x48, 0x72, 0x0e, - 0xe6, 0xe9, 0xc2, 0x1a, 0xc3, 0x64, 0x6f, 0x31, 0xee, 0x2d, 0xc6, 0xd7, 0x6a, 0x31, 0xee, 0x6d, - 0xb8, 0xbd, 0x0d, 0xf7, 0xcc, 0x6d, 0x38, 0x26, 0x9e, 0xab, 0x9a, 0x71, 0x41, 0x61, 0x75, 0xdc, - 0x1b, 0x76, 0x7b, 0xc3, 0x6e, 0x6f, 0xd8, 0x3d, 0x91, 0x61, 0xf7, 0x82, 0x2c, 0xaf, 0xca, 0xfb, - 0xc6, 0xdb, 0xdb, 0x64, 0xeb, 0x95, 0xd0, 0x2a, 0x27, 0x36, 0xf7, 0xa6, 0x97, 0x6e, 0x7a, 0x59, - 0x9e, 0x37, 0xa3, 0x1b, 0xe5, 0xc0, 0xae, 0x6a, 0x37, 0xdb, 0x9f, 0x39, 0x7b, 0x1c, 0x8b, 0xad, - 0x68, 0x5f, 0xb1, 0x1c, 0x65, 0xa5, 0xea, 0x5e, 0x7c, 0x3c, 0xf9, 0xe5, 0xb4, 0xd6, 0xd9, 0xc2, - 0x92, 0x7b, 0x68, 0x7b, 0xcd, 0x6e, 0x91, 0x95, 0x5b, 0x74, 0xf7, 0xb1, 0xd7, 0xc4, 0xae, 0x62, - 0xd9, 0x24, 0xda, 0x9b, 0x69, 0x0f, 0x67, 0xa6, 0x3d, 0x03, 0xab, 0xe8, 0xd9, 0x59, 0x8a, 0x3b, - 0x36, 0xd3, 0xf6, 0x97, 0x50, 0x9f, 0xd1, 0x25, 0xd4, 0x57, 0x6e, 0x0e, 0x3f, 0xad, 0xf9, 0xf9, - 0xdc, 0x8c, 0xf1, 0x5d, 0x99, 0xc3, 0xff, 0x6f, 0xae, 0x05, 0xdf, 0xdf, 0xe4, 0x67, 0x70, 0x9b, - 0x6d, 0xde, 0x1a, 0x74, 0xa8, 0xbd, 0xcd, 0xbf, 0xb7, 0xf9, 0xf7, 0x36, 0xff, 0x43, 0xd8, 0xfc, - 0x62, 0x2a, 0xc6, 0xb2, 0x82, 0x5e, 0xee, 0x0b, 0xd8, 0xe6, 0x72, 0xaa, 0x22, 0x6f, 0xf4, 0x10, - 0x2e, 0x6b, 0x6d, 0xf2, 0xdd, 0x19, 0x1a, 0xaf, 0xe5, 0x6e, 0xe8, 0xcb, 0xdf, 0x29, 0x5f, 0xef, - 0x2a, 0x79, 0x46, 0x97, 0x4c, 0x9f, 0xd0, 0x95, 0xb3, 0x0f, 0x71, 0xfc, 0xba, 0x1e, 0x3e, 0x91, - 0xbb, 0x5a, 0x6e, 0x9f, 0xda, 0xe6, 0xe6, 0xd2, 0xe3, 0xbd, 0x16, 0xa8, 0xc1, 0x82, 0x35, 0xc0, - 0x95, 0x09, 0x67, 0x62, 0xc0, 0x89, 0xa8, 0xf6, 0x68, 0x7f, 0x97, 0x61, 0x04, 0x8a, 0xc3, 0x17, - 0xe5, 0x3f, 0x24, 0xd8, 0x96, 0xa8, 0x23, 0xc9, 0x55, 0x67, 0xbe, 0x40, 0x04, 0x6a, 0x3f, 0x37, - 0x97, 0x2a, 0x7c, 0x52, 0x0e, 0x9f, 0xa8, 0xf0, 0xab, 0x2e, 0x7e, 0x31, 0xb9, 0xce, 0x7b, 0x02, - 0x29, 0x38, 0xf4, 0x46, 0x17, 0xa7, 0x0f, 0xd3, 0xe4, 0x68, 0xb5, 0xae, 0xea, 0x1d, 0xfa, 0xec, - 0x8b, 0xab, 0x13, 0xb4, 0x12, 0xc8, 0x93, 0x6d, 0x90, 0x27, 0x76, 0xe4, 0x89, 0x60, 0x0c, 0x1c, - 0xf5, 0x64, 0xf3, 0x8b, 0xe7, 0x98, 0x83, 0x50, 0xaf, 0xfa, 0xa8, 0xe5, 0xae, 0x84, 0x2b, 0xd9, - 0xe2, 0xda, 0x38, 0xc5, 0x95, 0x20, 0x5c, 0x89, 0xab, 0x78, 0x7c, 0x01, 0x97, 0xf1, 0xea, 0x38, - 0xaa, 0xd4, 0x37, 0x67, 0x24, 0xae, 0xf9, 0xca, 0x38, 0xf1, 0x01, 0x3f, 0xe0, 0xfb, 0x13, 0x2f, - 0xd8, 0x03, 0x5c, 0xe9, 0xc4, 0x0e, 0x1d, 0x2c, 0xf2, 0x6c, 0x75, 0x5c, 0x50, 0xf0, 0x50, 0xef, - 0x77, 0x57, 0x52, 0xba, 0xa9, 0x54, 0x62, 0x29, 0x95, 0x3c, 0xd2, 0xe9, 0x20, 0x9a, 0x0a, 0x95, - 0xc4, 0xa6, 0xc4, 0x64, 0x1b, 0xa5, 0x70, 0x7f, 0xdf, 0x65, 0x7f, 0x7a, 0x69, 0x7f, 0x7a, 0xa9, - 0xdc, 0x2d, 0xce, 0x86, 0xcc, 0xe0, 0x33, 0x7b, 0x08, 0x97, 0x39, 0x76, 0x14, 0x95, 0x50, 0x29, - 0xf2, 0xad, 0x7d, 0x25, 0x40, 0x4c, 0xfc, 0x25, 0xe5, 0x96, 0xf5, 0xa6, 0x0a, 0xb6, 0xbf, 0xbc, - 0xb3, 0x3f, 0xf8, 0xf5, 0x4c, 0x0e, 0x7e, 0xed, 0xce, 0xb7, 0x2d, 0x4d, 0x45, 0xf1, 0xd3, 0x50, - 0xb3, 0xc8, 0xf4, 0xd5, 0xf9, 0x69, 0x6a, 0xb2, 0x8c, 0xc9, 0x38, 0xc9, 0xf6, 0x2e, 0xe8, 0xbd, - 0x0b, 0x7a, 0xef, 0x82, 0x7e, 0x85, 0x2e, 0x68, 0xac, 0xaa, 0x47, 0x54, 0x66, 0xf0, 0x79, 0xe9, - 0xe9, 0xd6, 0x47, 0x73, 0x19, 0x48, 0x02, 0x85, 0x8f, 0x5f, 0x01, 0x6c, 0x55, 0xe7, 0x86, 0x89, - 0x4b, 0xb1, 0x27, 0x6b, 0xb1, 0x27, 0xd5, 0xb0, 0x27, 0x12, 0x76, 0x88, 0x6e, 0x56, 0xcd, 0x4d, - 0xbe, 0x3e, 0x34, 0xd7, 0xa2, 0x7f, 0x89, 0xbb, 0xb5, 0x18, 0x63, 0x09, 0x59, 0x6c, 0xcf, 0xcc, - 0x0a, 0xda, 0xdf, 0xe2, 0x2a, 0x5f, 0x87, 0x77, 0xa7, 0x07, 0x3f, 0xae, 0x12, 0xfb, 0x12, 0x2f, - 0x94, 0x19, 0x31, 0x94, 0x1c, 0x04, 0x28, 0xf6, 0x78, 0x69, 0x87, 0x6f, 0xa0, 0xae, 0xbc, 0x40, - 0xff, 0x28, 0x12, 0x42, 0x90, 0xdb, 0x8d, 0x8d, 0xd1, 0x88, 0xb0, 0x28, 0x71, 0x9b, 0xb1, 0x06, - 0x9c, 0x58, 0x81, 0x93, 0x02, 0x30, 0x76, 0xe5, 0xf1, 0x5a, 0x7c, 0x8e, 0xc2, 0xc7, 0x72, 0xce, - 0x0d, 0x89, 0x63, 0x2e, 0x52, 0xde, 0x97, 0x3d, 0x6e, 0x08, 0xe9, 0x28, 0x4b, 0x68, 0x12, 0x50, - 0xd8, 0x94, 0x43, 0xd1, 0x3e, 0xfe, 0xf1, 0xcf, 0x4a, 0x27, 0x2c, 0xf3, 0x31, 0x5a, 0x41, 0xe6, - 0xf2, 0x63, 0x14, 0x5c, 0xe6, 0xe3, 0x15, 0xc5, 0x92, 0x99, 0x5c, 0x5d, 0x5e, 0xa6, 0xf3, 0xb2, - 0x87, 0x67, 0x37, 0x0c, 0xc3, 0xd5, 0x32, 0xa4, 0xb5, 0xb7, 0x8d, 0xcd, 0xd5, 0x8a, 0x1c, 0xc7, - 0x1c, 0xbb, 0xb0, 0x01, 0x27, 0x6f, 0x03, 0x95, 0xfe, 0x9a, 0x0b, 0x51, 0x86, 0x48, 0xc9, 0x76, - 0x44, 0x42, 0xb9, 0xc1, 0x03, 0xe7, 0x72, 0x07, 0x40, 0xf8, 0x29, 0xd1, 0x55, 0x52, 0xe7, 0xca, - 0x7b, 0xc9, 0xdd, 0xdc, 0x1a, 0xd3, 0xd2, 0xba, 0xd4, 0xb6, 0xec, 0x59, 0xed, 0xca, 0xdd, 0x54, - 0x18, 0x9d, 0x39, 0xc4, 0x40, 0x42, 0xaa, 0xc4, 0x02, 0x22, 0x72, 0x97, 0x65, 0x83, 0xb0, 0x2c, - 0x8e, 0x7c, 0x8c, 0xba, 0x0d, 0x87, 0x83, 0xd3, 0xdf, 0x37, 0x61, 0x10, 0xbd, 0x6c, 0x9a, 0xcf, - 0xe3, 0x85, 0xe9, 0xfd, 0x13, 0x78, 0xa9, 0x64, 0x31, 0x1b, 0x4d, 0xbb, 0x37, 0x38, 0x0a, 0xaf, - 0x76, 0xa4, 0x5c, 0x88, 0xe5, 0x56, 0x71, 0x62, 0xb6, 0x48, 0x50, 0xb1, 0xd6, 0x9a, 0x30, 0xb1, - 0x6d, 0x02, 0xd6, 0x26, 0xd1, 0xb8, 0x09, 0xb2, 0x66, 0x4c, 0x54, 0x7f, 0x54, 0x05, 0x4d, 0x98, - 0x0f, 0x92, 0x48, 0xfc, 0x0c, 0x18, 0x58, 0x78, 0xc7, 0x0b, 0xb5, 0xf5, 0x42, 0x6d, 0x51, 0xa8, - 0x2d, 0x0a, 0xb5, 0xa1, 0x90, 0xe6, 0xef, 0x27, 0xd8, 0x7c, 0x1a, 0x05, 0x96, 0x8d, 0x3e, 0x7d, - 0x54, 0xa9, 0x89, 0x64, 0x84, 0x14, 0xcd, 0x14, 0xba, 0x84, 0xe3, 0x05, 0xb4, 0x21, 0x7c, 0xe1, - 0x68, 0xda, 0x10, 0xc9, 0x1c, 0x7d, 0xf8, 0x6a, 0x8f, 0x41, 0x84, 0x7f, 0xd7, 0xb7, 0xe4, 0xdd, - 0x2e, 0x57, 0xd6, 0xbc, 0xd5, 0xed, 0x92, 0xc7, 0x45, 0x8b, 0xaf, 0x53, 0x24, 0x1d, 0xd2, 0x88, - 0xbd, 0x40, 0xc4, 0x9e, 0x95, 0x62, 0xef, 0x49, 0xb9, 0xc1, 0x21, 0x84, 0xb1, 0x84, 0x08, 0xe1, - 0x0e, 0x85, 0x6d, 0xa0, 0x2f, 0x08, 0xdf, 0x55, 0x1c, 0x7e, 0x20, 0x18, 0x2a, 0xc4, 0xb3, 0xc7, - 0x2b, 0x0c, 0x3f, 0x99, 0x3e, 0x64, 0xe8, 0x81, 0xa1, 0xc0, 0xbe, 0x26, 0x0d, 0xd4, 0x59, 0xd1, - 0x5f, 0x9b, 0xe0, 0x32, 0x44, 0xe8, 0xb7, 0x05, 0x0f, 0x54, 0xe1, 0x57, 0x48, 0xd1, 0x24, 0x2c, - 0x96, 0x14, 0x24, 0x5e, 0x18, 0x23, 0xd2, 0xe7, 0xd5, 0xf8, 0xb8, 0xed, 0x74, 0xf8, 0x7c, 0x16, - 0xe2, 0xeb, 0x7e, 0xf2, 0x17, 0xf5, 0xd2, 0x22, 0xa7, 0x53, 0xe6, 0xfc, 0x2c, 0x2a, 0x04, 0xdb, - 0x0b, 0x8d, 0x5b, 0x26, 0xd4, 0x5a, 0x36, 0x6f, 0x99, 0x28, 0xa9, 0x87, 0x50, 0x82, 0xdb, 0x49, - 0xaa, 0xcc, 0xe5, 0x5e, 0x47, 0x60, 0x4c, 0x5d, 0x08, 0x25, 0x59, 0x36, 0x06, 0x21, 0xb3, 0x20, - 0x1b, 0x6d, 0x10, 0xe8, 0xb1, 0x8b, 0x89, 0x8d, 0x25, 0x49, 0xaf, 0x01, 0x5d, 0xa6, 0x31, 0x96, - 0xa5, 0x05, 0x38, 0xf5, 0x05, 0x3e, 0x0c, 0x5b, 0x96, 0x69, 0xc9, 0xea, 0xc5, 0x13, 0xc4, 0x83, - 0x60, 0xc8, 0x41, 0xd0, 0x35, 0x24, 0x99, 0xd9, 0x3b, 0x08, 0x16, 0xf8, 0xd9, 0x28, 0xef, 0x0d, - 0x75, 0x5a, 0xe7, 0x59, 0x1e, 0xe7, 0x69, 0x77, 0xb1, 0x9a, 0x24, 0xd9, 0xd8, 0x52, 0x90, 0x84, - 0x98, 0xd3, 0x76, 0x93, 0x14, 0x21, 0xde, 0x1b, 0xe2, 0x08, 0x8c, 0x2f, 0x60, 0xf7, 0x60, 0xcd, - 0x06, 0x1a, 0x49, 0x1d, 0xc7, 0x49, 0x8a, 0x16, 0xae, 0x71, 0x3c, 0x4d, 0x2d, 0x10, 0x03, 0xf6, - 0x7a, 0x83, 0x96, 0x2d, 0x38, 0x00, 0x44, 0xb0, 0x9e, 0x8c, 0x47, 0x80, 0x98, 0xcb, 0x93, 0x78, - 0x16, 0x5a, 0x8e, 0x5c, 0x15, 0x4d, 0xbb, 0x82, 0x61, 0xa7, 0xb0, 0xe8, 0x33, 0x79, 0x79, 0x5c, - 0xe8, 0x31, 0x91, 0x3c, 0x2b, 0xf9, 0x49, 0x13, 0xe6, 0x1d, 0x55, 0x73, 0xd9, 0x39, 0x15, 0xac, - 0x79, 0x08, 0x0f, 0x20, 0x4b, 0x84, 0x0e, 0x61, 0xa9, 0x08, 0x54, 0xe6, 0xcb, 0x45, 0x3a, 0x98, - 0x40, 0xb0, 0x41, 0xc4, 0x79, 0xe3, 0x34, 0x6a, 0x68, 0xf3, 0xfa, 0xaf, 0xce, 0x77, 0xa6, 0xa8, - 0x42, 0x9f, 0xc2, 0x02, 0xf6, 0x83, 0x65, 0xfa, 0xc2, 0x3b, 0x23, 0x3f, 0xd8, 0x67, 0x2d, 0xea, - 0x54, 0x4c, 0x05, 0x88, 0x41, 0x42, 0xd0, 0x5f, 0xad, 0xef, 0x3e, 0xfd, 0xd5, 0xfe, 0xee, 0xb3, - 0x09, 0xec, 0x06, 0x38, 0x6e, 0x71, 0x78, 0x57, 0x83, 0x3e, 0xab, 0x41, 0x8d, 0xf7, 0xab, 0x90, - 0x57, 0x56, 0x44, 0x5c, 0xd6, 0x94, 0xf5, 0x88, 0xa9, 0x54, 0xa1, 0xf8, 0xd4, 0x34, 0xd5, 0x57, - 0x76, 0x9e, 0x8d, 0xa6, 0xf9, 0xba, 0x10, 0xda, 0x34, 0x12, 0x32, 0x97, 0x46, 0x48, 0x04, 0x0d, - 0x33, 0x21, 0x8d, 0x22, 0x15, 0x5b, 0x53, 0x1d, 0x45, 0x06, 0x45, 0xa4, 0x4b, 0xa4, 0xcf, 0x91, - 0xda, 0x4f, 0x07, 0x56, 0xc4, 0x41, 0x89, 0x08, 0xac, 0x7d, 0x38, 0x28, 0xc9, 0x0d, 0xac, 0x38, - 0x15, 0xda, 0x24, 0x97, 0x16, 0x25, 0x8f, 0x98, 0x65, 0x60, 0xa7, 0x80, 0x0b, 0x53, 0xa5, 0x1d, - 0x9b, 0x5e, 0xe0, 0x59, 0x0e, 0xa1, 0x27, 0xbd, 0xa8, 0x50, 0x9a, 0x9d, 0x8b, 0x42, 0x8a, 0x00, - 0x3b, 0xff, 0x44, 0xe5, 0x44, 0xed, 0x27, 0xcc, 0xa5, 0x41, 0xe7, 0x08, 0x7b, 0x59, 0xf1, 0x48, - 0x28, 0xac, 0x8e, 0xa5, 0x33, 0x91, 0xd5, 0xa0, 0xc9, 0xa3, 0x9a, 0x42, 0xc2, 0x5f, 0x8a, 0xf8, - 0x66, 0xba, 0x22, 0x99, 0x5a, 0xe7, 0x6b, 0x07, 0x91, 0xc4, 0x5e, 0x6e, 0xe3, 0x90, 0xd0, 0xfc, - 0x5d, 0x9e, 0x58, 0x1f, 0xaf, 0xe5, 0x2a, 0x28, 0x8c, 0x20, 0x86, 0x4c, 0x22, 0x53, 0x45, 0x00, - 0x6f, 0x4c, 0xbf, 0x09, 0xf5, 0x66, 0xe0, 0xf8, 0xb1, 0x0e, 0x9c, 0x9d, 0xc2, 0x07, 0xb4, 0xd4, - 0x85, 0xc6, 0x87, 0xe3, 0x57, 0x70, 0xc6, 0x2b, 0xbc, 0x93, 0xbb, 0x02, 0xcf, 0x76, 0xc4, 0xab, - 0xd3, 0x08, 0x87, 0x29, 0x95, 0x65, 0x40, 0x5d, 0xc3, 0xaf, 0xf2, 0x27, 0x29, 0xd8, 0x43, 0xd2, - 0x09, 0x07, 0x67, 0x2d, 0x2f, 0x08, 0x0e, 0xe4, 0x1a, 0xfb, 0xa4, 0x1d, 0x17, 0x61, 0xaf, 0x32, - 0x47, 0xe3, 0x63, 0x3f, 0x3d, 0x27, 0xc7, 0xd7, 0x7f, 0xf5, 0x68, 0xa4, 0x5f, 0xd9, 0xf3, 0x0c, - 0xb2, 0xd1, 0xb4, 0xba, 0xf0, 0x31, 0x91, 0x21, 0x51, 0x47, 0x2a, 0x81, 0x6a, 0x24, 0x3b, 0x4e, - 0x5b, 0x7d, 0xa8, 0x43, 0x5a, 0x2b, 0x1c, 0xa8, 0x09, 0x37, 0x75, 0xad, 0x3d, 0x1e, 0xdf, 0xb8, - 0x0a, 0x0e, 0x21, 0x5a, 0x2f, 0xe7, 0x4b, 0x29, 0xfe, 0xf4, 0x35, 0x95, 0xca, 0xe8, 0xdf, 0x40, - 0x5a, 0xa0, 0x60, 0xf4, 0xe5, 0x25, 0x88, 0x2d, 0x27, 0xf4, 0xd3, 0x51, 0x75, 0x28, 0x1e, 0x9d, - 0x5c, 0x68, 0x0a, 0x91, 0x9c, 0x8f, 0x84, 0x28, 0xb6, 0x29, 0x20, 0x0e, 0xaf, 0xa2, 0x4f, 0xd4, - 0x3e, 0x34, 0x54, 0xfd, 0x42, 0x5d, 0xf8, 0xf8, 0xb3, 0x55, 0xe0, 0x26, 0x81, 0xd8, 0xd9, 0x0a, - 0xd2, 0xd6, 0xf7, 0xba, 0x54, 0xd4, 0xb5, 0x3a, 0x6f, 0xa9, 0xa9, 0x14, 0x3e, 0x49, 0xa8, 0xa8, - 0xcd, 0xd7, 0xf6, 0x7b, 0x3a, 0xd3, 0x64, 0xd5, 0x0b, 0x3b, 0x9a, 0x28, 0x80, 0xa7, 0xd5, 0x6b, - 0x7d, 0x2f, 0x82, 0xfe, 0x26, 0xfe, 0x20, 0x97, 0x9c, 0xbb, 0xda, 0xab, 0xfc, 0x0f, 0xaf, 0xf2, - 0xdb, 0x3c, 0xc5, 0xa3, 0xf1, 0xb8, 0xec, 0xe4, 0x92, 0xc8, 0xb7, 0x1f, 0x5f, 0x12, 0x30, 0xa6, - 0x33, 0x4c, 0x52, 0x6e, 0x99, 0xf3, 0x5f, 0x05, 0x2b, 0x7b, 0xf9, 0x29, 0x1e, 0x67, 0x65, 0x14, - 0x8b, 0x7c, 0x3b, 0xc5, 0x02, 0xc6, 0x44, 0xb1, 0x94, 0x5b, 0x46, 0xb1, 0x0a, 0xf6, 0xa2, 0x0f, - 0x3b, 0xe1, 0xa6, 0x94, 0x9c, 0x9b, 0x11, 0xf9, 0xf6, 0x47, 0x59, 0x39, 0x88, 0xf1, 0x61, 0x56, - 0x91, 0x5b, 0xfa, 0x30, 0x97, 0x02, 0xb6, 0x8e, 0x60, 0xfb, 0xb9, 0x36, 0x9e, 0x5d, 0x4e, 0xae, - 0xed, 0x84, 0x9b, 0xc8, 0x5c, 0x4b, 0xac, 0xb2, 0x37, 0xf1, 0x1c, 0x6d, 0xc1, 0xc7, 0x34, 0xd9, - 0x37, 0x75, 0x1f, 0x98, 0x4c, 0xfc, 0x6a, 0x36, 0x2b, 0x48, 0x61, 0xc5, 0xed, 0x7a, 0x48, 0x13, - 0xdb, 0x95, 0xac, 0x55, 0x49, 0xca, 0x89, 0x9f, 0xa6, 0x23, 0x56, 0x22, 0xd7, 0x57, 0x65, 0x9f, - 0xe9, 0xb0, 0x95, 0x8c, 0x6a, 0x2b, 0xf9, 0x25, 0x7e, 0x9a, 0x68, 0x11, 0xb9, 0xbe, 0x2a, 0xd5, - 0x4c, 0xb4, 0xc8, 0xa8, 0x36, 0x97, 0x4c, 0x3b, 0x3f, 0x9b, 0x25, 0x09, 0x1c, 0xf1, 0xd3, 0xf4, - 0x16, 0x2f, 0xcf, 0xf4, 0x55, 0x29, 0x64, 0x7c, 0x93, 0x57, 0xc2, 0xb4, 0x8d, 0x28, 0xe1, 0xbf, - 0x6c, 0x84, 0xd0, 0x53, 0x71, 0x92, 0x74, 0xb1, 0x92, 0x41, 0xb7, 0x2e, 0x8b, 0x32, 0x62, 0xef, - 0xd5, 0xd8, 0x7b, 0x35, 0xf6, 0x5e, 0x8d, 0xbd, 0x57, 0x63, 0xef, 0xd5, 0x78, 0x3d, 0x5e, 0x0d, - 0x76, 0x22, 0x58, 0x9c, 0x79, 0x53, 0x4e, 0xc9, 0x11, 0x3e, 0x78, 0x56, 0x8e, 0x0f, 0xf1, 0x5a, - 0xd2, 0x7c, 0x96, 0x8d, 0x63, 0x68, 0xfd, 0x3d, 0x3c, 0x21, 0x54, 0x3f, 0x23, 0x27, 0xdc, 0x50, - 0xdb, 0x9a, 0x4b, 0xb8, 0x73, 0x85, 0xaf, 0x8e, 0x11, 0x25, 0x8d, 0x6c, 0x20, 0x4a, 0x1d, 0xe4, - 0x93, 0x67, 0x40, 0x6d, 0xf5, 0x93, 0x60, 0x72, 0xf4, 0xf2, 0xd3, 0xc5, 0xa7, 0xcf, 0xdd, 0xf3, - 0x3f, 0x6b, 0xef, 0xa4, 0xfb, 0x50, 0xa7, 0x9f, 0x7e, 0x3e, 0xed, 0xfe, 0x7c, 0xf2, 0xeb, 0xaf, - 0x27, 0xa8, 0xb5, 0xed, 0xd6, 0xb1, 0xe1, 0x30, 0xcc, 0x41, 0x51, 0x6b, 0x86, 0xc5, 0xb8, 0x82, - 0x1d, 0xbc, 0x5b, 0x1b, 0x76, 0x87, 0xf6, 0xe7, 0xae, 0x4c, 0xc8, 0x9d, 0xda, 0x7f, 0x8f, 0x60, - 0xbe, 0x99, 0xbc, 0x79, 0x66, 0x93, 0x47, 0x3e, 0x6d, 0x65, 0xb1, 0xd2, 0xee, 0x61, 0xc8, 0x94, - 0x72, 0xe9, 0x66, 0x76, 0x48, 0xb9, 0x19, 0xb2, 0x91, 0x19, 0xf1, 0x18, 0xa7, 0xef, 0x24, 0xe6, - 0xd9, 0x4c, 0x9f, 0x2f, 0xe3, 0x8c, 0xcd, 0x54, 0x72, 0x10, 0xcf, 0x74, 0x78, 0x40, 0xb1, 0x2e, - 0x8a, 0x74, 0x3a, 0x4c, 0xfc, 0xb2, 0x3a, 0xd6, 0x07, 0x59, 0xe2, 0x4a, 0x96, 0xcc, 0xac, 0xf1, - 0x34, 0x53, 0xe8, 0xd8, 0x15, 0x75, 0x1a, 0x11, 0xb4, 0x81, 0x8c, 0x84, 0x34, 0xa4, 0x32, 0xfb, - 0x61, 0xe2, 0x22, 0x21, 0x0a, 0x03, 0x87, 0xe3, 0xf7, 0x14, 0xd6, 0x74, 0x43, 0xf9, 0x4c, 0xe5, - 0xd5, 0xe5, 0x65, 0xe4, 0x60, 0x55, 0xb9, 0x81, 0xef, 0x2d, 0x50, 0xb5, 0x99, 0x2b, 0xe2, 0xd0, - 0x3f, 0xec, 0x30, 0x4e, 0x24, 0xb1, 0x00, 0xa9, 0xce, 0xe1, 0xdd, 0xe7, 0xb5, 0x9b, 0xed, 0xf7, - 0x01, 0x11, 0xce, 0x75, 0x41, 0x85, 0x5b, 0x42, 0x06, 0xa9, 0x1b, 0x6a, 0x16, 0xa3, 0x19, 0x88, - 0x05, 0x95, 0x22, 0x0b, 0xef, 0x24, 0x72, 0xf1, 0x91, 0x40, 0x93, 0xbf, 0x18, 0xbc, 0xc5, 0xcd, - 0xb8, 0xd8, 0x21, 0xa4, 0xae, 0x7e, 0x84, 0x3f, 0x3c, 0x79, 0x82, 0x2a, 0x6a, 0x0e, 0xf6, 0x55, - 0x4b, 0x87, 0x08, 0x81, 0xb4, 0x86, 0x8c, 0xc0, 0x87, 0x94, 0xba, 0x92, 0x52, 0xf1, 0xc4, 0xa0, - 0xa7, 0xae, 0x64, 0xf7, 0xf2, 0x65, 0xff, 0x1f, 0x03, 0x90, 0xfe, 0x1c + 0xc5, 0x51, 0x54, 0x00, 0x59, 0xdd, 0x5c, 0x42, 0x47, 0x08, 0xc0, 0xc3, 0x11, 0xd3, 0xf5, 0x86, + 0x71, 0xaf, 0x94, 0x45, 0x32, 0xe8, 0x4a, 0xac, 0xd2, 0xae, 0x2c, 0x55, 0xd2, 0xc2, 0x6a, 0x20, + 0x6c, 0x1e, 0xa3, 0xd5, 0x77, 0x61, 0xa6, 0x8c, 0xe4, 0x29, 0xa4, 0x31, 0x35, 0x80, 0xb6, 0x98, + 0x40, 0x70, 0xea, 0x14, 0x25, 0xa1, 0x46, 0x33, 0x35, 0x0a, 0x55, 0x18, 0x56, 0xc9, 0x1a, 0x2a, + 0x93, 0xf1, 0x95, 0xa5, 0xf7, 0x20, 0x47, 0xa1, 0x10, 0xe7, 0x52, 0xf2, 0x20, 0x93, 0x13, 0x27, + 0x15, 0xc3, 0xe9, 0x1a, 0x5d, 0x05, 0xac, 0x6b, 0x48, 0xa2, 0x1c, 0x6e, 0x2e, 0x4f, 0x33, 0xad, + 0x84, 0x71, 0x75, 0xa1, 0x48, 0x9b, 0x98, 0x39, 0x76, 0xf2, 0x24, 0x98, 0x12, 0x0a, 0x17, 0xf9, + 0x3c, 0xfb, 0x77, 0x5a, 0xc6, 0x7a, 0x32, 0x84, 0x9d, 0x03, 0x65, 0x28, 0x13, 0x23, 0x2a, 0xf9, + 0x65, 0xfc, 0xa8, 0x03, 0xae, 0xa7, 0xfd, 0x66, 0xd4, 0xcf, 0x87, 0xa5, 0xb4, 0x63, 0x88, 0x32, + 0x16, 0x95, 0xe1, 0x2c, 0x8c, 0xaa, 0x80, 0xac, 0x61, 0x57, 0x1d, 0x76, 0x7d, 0x1b, 0x4a, 0x19, + 0x45, 0x85, 0xb1, 0xf2, 0x8b, 0x0a, 0x66, 0x62, 0x1b, 0x0d, 0xa2, 0x8c, 0x7b, 0x8a, 0xa0, 0xc4, + 0x5d, 0x20, 0x16, 0xc8, 0x43, 0xb4, 0x40, 0xf6, 0xe3, 0x3c, 0x96, 0xd6, 0x47, 0xf8, 0x85, 0xd6, + 0xc8, 0x52, 0xf1, 0xd6, 0x23, 0x8a, 0xae, 0x6e, 0x62, 0x52, 0x19, 0xe6, 0x73, 0x51, 0xe7, 0x32, + 0xf2, 0x74, 0x69, 0x16, 0x6d, 0x24, 0xb3, 0xc8, 0x9f, 0x48, 0xb7, 0x9d, 0x99, 0x54, 0xf2, 0x85, + 0x00, 0xe3, 0x15, 0x9a, 0x04, 0x54, 0xb4, 0x89, 0x0c, 0x82, 0x7f, 0x0c, 0x35, 0x42, 0xb2, 0xcf, + 0x84, 0x11, 0xaf, 0x4d, 0x93, 0x38, 0xd1, 0x46, 0x72, 0x85, 0xfe, 0x35, 0x54, 0x46, 0x73, 0x7c, + 0x49, 0xcc, 0x98, 0xaa, 0xe4, 0x08, 0xb6, 0x11, 0x17, 0xf2, 0x87, 0x69, 0x44, 0xe5, 0x7c, 0x5f, + 0x17, 0x24, 0xa6, 0xf1, 0x55, 0x11, 0x6e, 0x2d, 0x0a, 0xe4, 0x0f, 0x43, 0xd7, 0xc8, 0xd9, 0xbe, + 0x2e, 0x23, 0x2c, 0x5c, 0xa0, 0xa2, 0xbc, 0xc7, 0x04, 0x57, 0x3f, 0xed, 0xd4, 0x89, 0xf1, 0xd3, + 0x67, 0xbf, 0x69, 0x18, 0x75, 0xac, 0xd6, 0xe9, 0x8b, 0x7d, 0x56, 0x44, 0xa1, 0x89, 0x70, 0x85, + 0xa0, 0x2e, 0x12, 0xbb, 0x06, 0xdc, 0x5d, 0x1e, 0xfa, 0xa7, 0x21, 0xb4, 0xc6, 0xde, 0x68, 0xde, + 0x43, 0x7a, 0x13, 0xd1, 0x69, 0x22, 0x54, 0x15, 0x1e, 0x56, 0x04, 0xec, 0xb5, 0x9a, 0xc7, 0x6e, + 0x88, 0x8c, 0x70, 0x47, 0xd7, 0x9e, 0x98, 0x8a, 0xdc, 0xcb, 0xe6, 0x53, 0xa4, 0x07, 0xcd, 0x98, + 0x25, 0xa5, 0xa0, 0xa2, 0x25, 0x55, 0xad, 0x0c, 0x95, 0xd4, 0x0a, 0xd5, 0x23, 0x4a, 0xaa, 0xe7, + 0x90, 0xc9, 0x57, 0x97, 0xfb, 0x1d, 0x34, 0x48, 0x55, 0x37, 0xbb, 0xab, 0x41, 0xbf, 0x50, 0x37, + 0xd4, 0x6c, 0x9e, 0xfd, 0x2b, 0xed, 0xe5, 0x69, 0x9f, 0x91, 0xaf, 0xda, 0x72, 0x0a, 0x3d, 0xc4, + 0xa6, 0xbb, 0x5f, 0xed, 0x9e, 0xa3, 0xd7, 0xd8, 0xbc, 0x09, 0x4a, 0x34, 0x43, 0x64, 0x51, 0xd9, + 0x2d, 0x4d, 0x8d, 0x14, 0xea, 0x66, 0xa0, 0xcd, 0x2b, 0x29, 0x56, 0x6c, 0x94, 0xa5, 0xa7, 0x25, + 0x1c, 0xcd, 0xe5, 0x6a, 0xd3, 0xa6, 0x96, 0x29, 0xbc, 0x06, 0x2a, 0xb7, 0xa8, 0x41, 0x2e, 0x7d, + 0x13, 0xde, 0xdd, 0x49, 0xbc, 0x1e, 0x4f, 0xf3, 0x51, 0x3c, 0x1e, 0xc5, 0x0b, 0x2c, 0x2e, 0x11, + 0xb3, 0x06, 0x9f, 0x4e, 0xff, 0x38, 0xfb, 0x78, 0xda, 0x3d, 0x3f, 0xfb, 0xf3, 0xf4, 0x97, 0xee, + 0xb7, 0x93, 0xdf, 0xce, 0xbe, 0x06, 0xc6, 0x5a, 0x42, 0xb2, 0x60, 0x01, 0xe3, 0x1f, 0x3a, 0xb4, + 0xbe, 0xe6, 0xd2, 0x67, 0xbf, 0x56, 0xbe, 0x82, 0xda, 0xa5, 0x8e, 0x2e, 0xeb, 0x4a, 0xf6, 0xd8, + 0xea, 0xf6, 0x6e, 0x14, 0xe6, 0x47, 0xd6, 0x7c, 0x77, 0xa7, 0xbc, 0x3e, 0x85, 0xd2, 0xf9, 0x94, + 0xaa, 0xe2, 0x13, 0xe8, 0x77, 0x54, 0xb7, 0xb3, 0x4d, 0x88, 0x2a, 0x9a, 0x9a, 0x95, 0xdb, 0x2b, + 0x6b, 0x5d, 0x16, 0x3e, 0x5e, 0xaf, 0x47, 0xd9, 0x99, 0xb4, 0xaa, 0x42, 0xb4, 0x86, 0x03, 0x37, + 0xd7, 0x64, 0xd6, 0xb0, 0xd7, 0x56, 0x3a, 0xc8, 0x5a, 0xc6, 0xb9, 0xb7, 0xde, 0x80, 0xd9, 0x02, + 0x09, 0xf5, 0x90, 0x20, 0x61, 0x92, 0x7b, 0x9c, 0x4e, 0x07, 0x88, 0x32, 0xf2, 0x87, 0xc9, 0x57, + 0x37, 0xb4, 0x8a, 0x6e, 0x8a, 0xe7, 0x36, 0xd4, 0x32, 0xd1, 0x02, 0x8a, 0xf3, 0x1b, 0x93, 0x78, + 0xe9, 0x60, 0xa5, 0x59, 0x93, 0xcb, 0xca, 0x48, 0x75, 0xf3, 0x68, 0x31, 0xc9, 0xb2, 0x7c, 0xb8, + 0xc8, 0xd3, 0x99, 0xd3, 0x6a, 0xb6, 0x7c, 0x1d, 0x91, 0xaf, 0x12, 0x48, 0xf4, 0x1b, 0x82, 0x83, + 0xea, 0xa2, 0x91, 0xdc, 0x97, 0xb5, 0x7f, 0xd4, 0x10, 0x96, 0x76, 0xed, 0x27, 0xf8, 0x53, 0xfb, + 0x50, 0x93, 0xb0, 0x17, 0x30, 0x43, 0x75, 0x1a, 0x76, 0xc2, 0xb0, 0xe6, 0x05, 0x48, 0x73, 0x8d, + 0xf1, 0x16, 0x78, 0xdc, 0x49, 0xe6, 0x31, 0xbd, 0x4f, 0xe6, 0x18, 0x4f, 0xd3, 0x09, 0x25, 0x0d, + 0xfa, 0x1e, 0x8e, 0xb3, 0xc7, 0xde, 0x12, 0xb1, 0xef, 0x72, 0x08, 0x72, 0xac, 0x2b, 0xec, 0x4d, + 0x8a, 0xe6, 0x52, 0x6e, 0x16, 0x5d, 0x24, 0xcf, 0xec, 0x8a, 0x80, 0x76, 0x90, 0x7c, 0xcd, 0x09, + 0x41, 0x0a, 0xd3, 0x2c, 0xe3, 0x52, 0xa0, 0xa2, 0xdf, 0x85, 0x47, 0x6c, 0xb3, 0x35, 0xbc, 0xdc, + 0xd1, 0xc9, 0x0a, 0x99, 0xbd, 0x95, 0x36, 0xb7, 0x38, 0x4b, 0x1f, 0x21, 0x1d, 0x6e, 0xba, 0x80, + 0x9c, 0x2a, 0x3b, 0x29, 0xb4, 0x8e, 0x90, 0xec, 0x60, 0xca, 0xbd, 0xf7, 0xcf, 0xd3, 0x6f, 0x5f, + 0xb1, 0x4a, 0x86, 0xb7, 0xae, 0x83, 0xf6, 0x9b, 0x66, 0x2b, 0xe4, 0x1b, 0x73, 0x3f, 0x9f, 0xfc, + 0x7e, 0x71, 0xd1, 0xfd, 0xf8, 0xf5, 0xf4, 0x33, 0x9a, 0x59, 0x87, 0xef, 0xdf, 0xbd, 0x3f, 0xea, + 0x74, 0xde, 0xb5, 0x8e, 0x5a, 0xed, 0xa3, 0xc3, 0xce, 0xdb, 0x83, 0xaa, 0x5e, 0x04, 0xca, 0x19, + 0xe4, 0x8f, 0xc1, 0x7e, 0x22, 0x19, 0xbe, 0x60, 0x13, 0xcd, 0xd0, 0x94, 0x19, 0x21, 0xda, 0x6c, + 0xb4, 0xcd, 0x4b, 0xd4, 0x83, 0x7b, 0x16, 0xe8, 0x09, 0x08, 0x3c, 0x82, 0xfd, 0x6e, 0x25, 0x6b, + 0x8d, 0x20, 0xbc, 0x88, 0x16, 0xff, 0x3b, 0xcf, 0x9d, 0x06, 0x4a, 0xf6, 0xc6, 0xd9, 0xc0, 0x81, + 0xd1, 0x08, 0x48, 0x03, 0x03, 0x69, 0x8c, 0x03, 0x31, 0x10, 0xae, 0x1b, 0x1c, 0xa2, 0x21, 0xe2, + 0x43, 0x1a, 0x5d, 0x78, 0x7a, 0xc5, 0xa1, 0x26, 0xfb, 0x99, 0x1e, 0x4f, 0x88, 0x2e, 0xd8, 0x60, + 0xc4, 0xf6, 0xca, 0x16, 0x64, 0x92, 0xeb, 0x26, 0x63, 0x9d, 0x02, 0x13, 0x21, 0x61, 0x94, 0x24, + 0xc0, 0x6f, 0xeb, 0xc4, 0xc2, 0x03, 0x4d, 0x6d, 0x33, 0x90, 0x98, 0x0b, 0x16, 0xb6, 0xdf, 0x98, + 0xa1, 0xad, 0x6a, 0x13, 0x6d, 0x4e, 0x15, 0xc6, 0x24, 0xb9, 0xfd, 0xa8, 0x81, 0xba, 0xd1, 0x43, + 0x63, 0x86, 0xff, 0xef, 0x67, 0xb9, 0xc3, 0xe9, 0xf2, 0xf9, 0x2f, 0xc6, 0x0f, 0xd7, 0xf1, 0x38, + 0x22, 0x68, 0x3c, 0xa9, 0x59, 0x9e, 0x20, 0xdb, 0x4b, 0x97, 0x33, 0xa7, 0xaf, 0xad, 0x4a, 0x78, + 0xe0, 0x50, 0x51, 0xd8, 0x3d, 0x62, 0xff, 0xbb, 0x3b, 0xd8, 0x87, 0xbe, 0xc9, 0xe6, 0xe3, 0x7e, + 0xd5, 0x9d, 0xdc, 0x8d, 0x96, 0x24, 0x8f, 0x22, 0x97, 0xb6, 0x6e, 0x9b, 0xcb, 0x28, 0x26, 0x7f, + 0xe9, 0xf7, 0x0a, 0xc4, 0x56, 0x83, 0xa4, 0xad, 0xe4, 0xcd, 0xce, 0xe2, 0xce, 0xa1, 0x29, 0x87, + 0x2c, 0xc9, 0x73, 0x94, 0x62, 0xdf, 0xf5, 0x5f, 0xd3, 0x08, 0x7a, 0x54, 0xc4, 0xb0, 0xab, 0x86, + 0x81, 0xdd, 0xe6, 0x5c, 0xda, 0x7c, 0x53, 0xa0, 0x44, 0xe5, 0x3e, 0x96, 0x12, 0xb9, 0x0f, 0x73, + 0x4d, 0x1b, 0xd6, 0x7b, 0x1d, 0x2c, 0x68, 0x55, 0xd1, 0x1d, 0x0a, 0x89, 0xf1, 0xb4, 0x37, 0xcc, + 0xe6, 0xe6, 0x3c, 0x36, 0x99, 0x8a, 0x98, 0xc6, 0x71, 0x2f, 0x35, 0xf0, 0xc1, 0x62, 0x38, 0xba, + 0xcc, 0xc3, 0x4a, 0x9c, 0x54, 0xbe, 0x06, 0xda, 0x5d, 0x17, 0x6c, 0x84, 0xe8, 0xec, 0x61, 0xa4, + 0xe8, 0xc9, 0xd3, 0x2c, 0xff, 0x7d, 0x01, 0xe9, 0xda, 0xbe, 0xb0, 0xe4, 0x73, 0x3a, 0xcf, 0xd0, + 0x74, 0x2b, 0xb0, 0xa2, 0xe8, 0x0f, 0xc2, 0x89, 0xf2, 0xbc, 0x17, 0x54, 0x51, 0x28, 0x46, 0x55, + 0xa4, 0x22, 0x6d, 0xde, 0xa8, 0xc5, 0xb2, 0xf1, 0x18, 0x9f, 0xbd, 0xe9, 0xce, 0xd2, 0xf9, 0x62, + 0x86, 0xe0, 0x46, 0xd7, 0x29, 0x62, 0x05, 0x34, 0x15, 0xa2, 0xde, 0x18, 0x71, 0x04, 0x1a, 0xba, + 0xe3, 0x3a, 0xc8, 0x0c, 0xa7, 0xa4, 0xe5, 0x81, 0xb5, 0x76, 0x17, 0xab, 0xb8, 0x47, 0x30, 0xfc, + 0x6b, 0xf5, 0x3e, 0x26, 0x2a, 0x74, 0xcf, 0x8f, 0xc3, 0x47, 0xbb, 0x4e, 0x87, 0x71, 0x8d, 0xbf, + 0xc7, 0x2b, 0x69, 0x55, 0xc8, 0x86, 0x25, 0x62, 0xac, 0x82, 0xa7, 0x30, 0x1d, 0x13, 0x91, 0x88, + 0xe7, 0xf0, 0x7d, 0x06, 0x94, 0x1a, 0x25, 0xe3, 0xd9, 0x30, 0x8e, 0x50, 0xff, 0x85, 0x46, 0x29, + 0x87, 0x1b, 0xcd, 0x1a, 0xee, 0x61, 0x60, 0xec, 0x71, 0x63, 0x55, 0xd5, 0xfe, 0xab, 0x06, 0x53, + 0xd1, 0xa4, 0xff, 0x4a, 0x25, 0xf1, 0x74, 0xa5, 0xa5, 0xef, 0x48, 0x71, 0x4a, 0x92, 0xb1, 0xbc, + 0x17, 0x35, 0xdb, 0xe1, 0xdd, 0x4e, 0x66, 0xe1, 0xb3, 0x9a, 0x6e, 0x5a, 0xba, 0xb6, 0xad, 0xac, + 0x2d, 0xd2, 0xe6, 0x64, 0xa6, 0xa4, 0xec, 0x67, 0xae, 0x71, 0xe6, 0xca, 0xf4, 0xcd, 0xe2, 0x7e, + 0x1f, 0x75, 0x60, 0xf7, 0x32, 0xee, 0xe5, 0x19, 0xf8, 0x59, 0x3b, 0x85, 0x89, 0xcd, 0xf9, 0xa7, + 0x30, 0x9d, 0xd5, 0xc2, 0x8f, 0x31, 0xbb, 0xd9, 0xf8, 0x47, 0x71, 0xb2, 0x10, 0x02, 0xa6, 0xb9, + 0x72, 0x25, 0x65, 0x56, 0xd0, 0xa7, 0xd2, 0x13, 0x6a, 0xfc, 0x10, 0x6d, 0xe0, 0xdf, 0x2e, 0xa5, + 0x5e, 0x52, 0x1b, 0xf8, 0xea, 0x7f, 0x8d, 0xa0, 0xb0, 0xf7, 0x9d, 0xd5, 0xfd, 0x3c, 0xb8, 0x5e, + 0x17, 0x6f, 0x92, 0x6a, 0xb1, 0xb1, 0x70, 0xeb, 0x6d, 0x2b, 0xd5, 0x7a, 0x54, 0x9c, 0x75, 0xd8, + 0x11, 0x67, 0x85, 0x60, 0xcd, 0xa1, 0xa4, 0x35, 0xc7, 0x2d, 0xf5, 0x3e, 0x09, 0x5d, 0xd8, 0x33, + 0xe1, 0x0c, 0x0d, 0x1e, 0xb5, 0x36, 0xb2, 0x58, 0x8d, 0xc0, 0x81, 0x61, 0x14, 0x15, 0x0b, 0x8e, + 0x8d, 0x4a, 0x59, 0x55, 0x8c, 0x7f, 0x80, 0xa5, 0xd2, 0xfe, 0x20, 0xc5, 0x7c, 0x6b, 0x74, 0x1d, + 0x95, 0xfa, 0xb7, 0x1a, 0xca, 0xe6, 0x25, 0xf4, 0x74, 0x43, 0xc7, 0x6c, 0x75, 0x32, 0x11, 0xef, + 0xe3, 0xdd, 0xee, 0x0e, 0xc3, 0x1a, 0x36, 0x3e, 0xd6, 0x1e, 0x7d, 0xdd, 0x90, 0xbe, 0x97, 0x76, + 0x92, 0xea, 0x39, 0x1d, 0x08, 0x2a, 0x18, 0xa8, 0x4f, 0x7e, 0x66, 0x63, 0x07, 0xc7, 0x1a, 0xaa, + 0xf2, 0xf0, 0x93, 0x6c, 0xfc, 0x3d, 0xf0, 0xa6, 0xd9, 0x23, 0x6f, 0xdc, 0x6c, 0xb4, 0x7b, 0x62, + 0xb0, 0x45, 0x1f, 0xe4, 0xf8, 0xe7, 0x06, 0xb2, 0xc2, 0xe8, 0x6f, 0x30, 0x58, 0xe5, 0xb6, 0xc1, + 0xb9, 0xca, 0xc7, 0xa3, 0x69, 0xe9, 0x51, 0x39, 0x05, 0xc4, 0x2e, 0x63, 0x14, 0x30, 0x93, 0xac, + 0x51, 0x01, 0xca, 0xb8, 0xaa, 0x00, 0xf9, 0x8a, 0x64, 0x8f, 0xda, 0xe1, 0xca, 0x97, 0x49, 0x16, + 0x29, 0x00, 0x7e, 0x61, 0x30, 0x4c, 0xb2, 0x49, 0xc3, 0xb9, 0x55, 0x6f, 0x3e, 0xb5, 0xac, 0xc2, + 0x3c, 0x1b, 0x39, 0xaa, 0x6e, 0x1e, 0x28, 0x1a, 0x77, 0x1d, 0x26, 0x4d, 0x00, 0x5e, 0x61, 0xc6, + 0xf5, 0x56, 0x01, 0xa7, 0xf6, 0xf9, 0xce, 0x59, 0xf3, 0xa1, 0xb8, 0x6b, 0x8d, 0xab, 0xcd, 0x22, + 0xcf, 0x94, 0xb6, 0x6f, 0xc3, 0x26, 0xf7, 0x94, 0x91, 0x42, 0x53, 0x14, 0x6a, 0x2c, 0xa2, 0xbd, + 0xc1, 0xa5, 0x60, 0x36, 0x47, 0xf6, 0xd0, 0x8a, 0x29, 0x88, 0x44, 0x79, 0x07, 0xb7, 0xa5, 0xb6, + 0x01, 0x0a, 0xca, 0x37, 0x60, 0xd1, 0x35, 0x41, 0x99, 0x6c, 0xcf, 0xc1, 0xc5, 0x99, 0x10, 0xde, + 0x9d, 0x83, 0xf7, 0xe1, 0x6e, 0x10, 0xb1, 0xb3, 0x1b, 0xd8, 0xb8, 0xb9, 0xef, 0x0d, 0xa0, 0xea, + 0xcb, 0xc0, 0xb3, 0x3f, 0xd2, 0xcd, 0xee, 0x71, 0x5c, 0xce, 0xb3, 0x89, 0x19, 0x8f, 0x0c, 0x61, + 0xa4, 0x15, 0x56, 0x29, 0x19, 0x48, 0x25, 0x98, 0x5e, 0x04, 0x95, 0xb2, 0x4d, 0x44, 0xd3, 0xe1, + 0xd1, 0xe1, 0x2a, 0x10, 0x9e, 0x67, 0xe5, 0x64, 0x23, 0x43, 0x67, 0x1d, 0xd1, 0x79, 0x56, 0x42, + 0x32, 0xca, 0xac, 0x40, 0x30, 0x81, 0xaa, 0xbe, 0x5a, 0x3d, 0xd5, 0x91, 0x5c, 0x65, 0xb8, 0xe5, + 0x8f, 0x28, 0xee, 0x9a, 0x06, 0x49, 0xda, 0x8b, 0x56, 0x47, 0x31, 0xda, 0x76, 0xb0, 0xc4, 0xcf, + 0x28, 0xee, 0x16, 0x3b, 0xd9, 0x58, 0x21, 0x82, 0x35, 0x77, 0xb5, 0x7c, 0x91, 0x16, 0x2e, 0x4d, + 0x45, 0x32, 0x4d, 0x70, 0xe8, 0x44, 0x81, 0x80, 0xdb, 0x53, 0x2a, 0xc4, 0xed, 0x4d, 0xa8, 0xe3, + 0x48, 0x22, 0x51, 0x91, 0x09, 0x83, 0x92, 0x8f, 0xca, 0x53, 0x07, 0x18, 0x08, 0x9e, 0x6f, 0xd8, + 0x1f, 0x47, 0x85, 0x4c, 0x73, 0x19, 0x8a, 0xfb, 0xbc, 0x6a, 0x0e, 0x3b, 0x0b, 0x03, 0x24, 0x5c, + 0x50, 0x9f, 0x12, 0xc9, 0x61, 0xc7, 0x5b, 0xf2, 0x4c, 0x4d, 0xbf, 0x09, 0xab, 0x2d, 0xef, 0x40, + 0x2b, 0x12, 0xe6, 0xb3, 0x71, 0xbc, 0xa2, 0x37, 0x04, 0xc9, 0x56, 0xb0, 0x23, 0x77, 0x41, 0x73, + 0xd9, 0x90, 0xfb, 0xac, 0xb9, 0x74, 0x03, 0x41, 0xbe, 0xaf, 0x82, 0xae, 0x54, 0xd0, 0x95, 0x0c, + 0x6a, 0xaa, 0x2f, 0x29, 0xd6, 0x97, 0xa8, 0xf5, 0x25, 0x25, 0xf5, 0x25, 0x6a, 0x7d, 0x49, 0xa1, + 0xbe, 0x7b, 0x5e, 0xa4, 0xe4, 0x1d, 0xee, 0xa9, 0x9d, 0xe4, 0xf3, 0x31, 0x7a, 0xa8, 0x9b, 0x93, + 0x74, 0x00, 0xd5, 0x7a, 0x12, 0x4b, 0x3d, 0x5b, 0x28, 0x64, 0x6b, 0x6e, 0x3b, 0xda, 0xf7, 0x21, + 0x99, 0x78, 0xbc, 0x8c, 0xfb, 0xe9, 0xa3, 0x2e, 0x79, 0xbb, 0x5b, 0xb5, 0x76, 0xbd, 0xdc, 0x3c, + 0xe6, 0x5a, 0xf1, 0x18, 0xc7, 0x0e, 0x95, 0xce, 0xda, 0x46, 0xa0, 0x97, 0xf6, 0xc6, 0x8b, 0x13, + 0xd8, 0x9b, 0x5d, 0xca, 0xb5, 0x5c, 0xc9, 0x7d, 0xa2, 0x0b, 0xb9, 0x96, 0xeb, 0xb8, 0x0f, 0x76, + 0x19, 0xf7, 0x91, 0x8d, 0x0a, 0xd3, 0xf5, 0x5e, 0x10, 0x44, 0xd4, 0xf3, 0xef, 0xed, 0x30, 0x8e, + 0xc1, 0xf3, 0xb0, 0x24, 0xf6, 0x66, 0xc3, 0xde, 0x6c, 0xd8, 0x9b, 0x0d, 0x7b, 0xb3, 0xc1, 0x62, + 0x36, 0xfc, 0x33, 0xcb, 0x26, 0xf7, 0x37, 0x1d, 0x5e, 0xbb, 0x55, 0xb0, 0x93, 0x18, 0x2c, 0xa5, + 0xa6, 0x03, 0x1f, 0xa7, 0x1d, 0x98, 0x0f, 0x85, 0xba, 0xd6, 0x5b, 0x03, 0x8a, 0xce, 0xff, 0x10, + 0x41, 0x4e, 0xf6, 0xaa, 0xff, 0x5e, 0xf5, 0xdf, 0xab, 0xfe, 0xaf, 0x4b, 0xf5, 0xaf, 0xa8, 0xa8, + 0xef, 0x46, 0x45, 0x3f, 0x44, 0xa9, 0x63, 0x38, 0x8b, 0xae, 0xc6, 0x46, 0x63, 0x53, 0x8a, 0x67, + 0xcb, 0xfb, 0xb7, 0x8a, 0x2c, 0xc1, 0xb9, 0xe2, 0x70, 0xbe, 0x2e, 0x09, 0xaf, 0xd3, 0x79, 0x3e, + 0x42, 0x12, 0xb6, 0x3b, 0x80, 0x63, 0x34, 0xe9, 0x34, 0x0f, 0xd7, 0x1f, 0x8f, 0x04, 0xd5, 0x6f, + 0x8a, 0x90, 0xa0, 0x52, 0xa9, 0xb2, 0x15, 0x7c, 0x84, 0xe4, 0x22, 0xdb, 0xdd, 0x31, 0x5f, 0x9d, + 0x8d, 0xad, 0x77, 0x63, 0x51, 0x8e, 0xfd, 0x6e, 0x12, 0xe4, 0x96, 0xdf, 0x51, 0x60, 0x10, 0x25, + 0xd2, 0x6b, 0x58, 0x72, 0x39, 0x6a, 0xb8, 0xe6, 0x72, 0xd4, 0xb0, 0xc2, 0x35, 0x89, 0x61, 0x95, + 0x3b, 0x31, 0xf7, 0x3d, 0x62, 0x53, 0xfd, 0xac, 0x44, 0x15, 0x35, 0x1a, 0x8f, 0x87, 0xdc, 0x0a, + 0x48, 0x30, 0xc5, 0xe0, 0x40, 0xc9, 0x3e, 0x1b, 0x24, 0xe3, 0xcd, 0x20, 0x52, 0x70, 0x83, 0x61, + 0x90, 0x0b, 0x0f, 0x6d, 0xb7, 0x92, 0x86, 0xec, 0x56, 0xd2, 0xb0, 0xec, 0x56, 0x12, 0x2b, 0xbe, + 0xc9, 0x08, 0x14, 0xcf, 0x6e, 0x3c, 0xe0, 0x31, 0x1d, 0x3c, 0x31, 0xc9, 0x0c, 0x89, 0xa4, 0xa9, + 0x82, 0x04, 0xf3, 0x6d, 0x88, 0x3b, 0x0a, 0xae, 0x68, 0x82, 0x77, 0x00, 0x3e, 0xdc, 0x90, 0xd2, + 0xcf, 0x12, 0xc9, 0x27, 0xf3, 0x2c, 0x90, 0xa0, 0x96, 0x04, 0x47, 0x73, 0x89, 0x2f, 0x30, 0xad, + 0xd5, 0xf3, 0x72, 0x7c, 0x54, 0xb0, 0x55, 0xfb, 0x89, 0x76, 0x4d, 0xed, 0x03, 0x1e, 0x1f, 0xd0, + 0xfe, 0xa4, 0x0b, 0x9c, 0xd7, 0x38, 0x14, 0x2d, 0xfe, 0xd9, 0x9c, 0x7b, 0xad, 0x66, 0xa7, 0xdd, + 0x79, 0x53, 0x27, 0x9f, 0x03, 0xf4, 0xf9, 0xb6, 0x7d, 0xdc, 0xa1, 0x9f, 0x09, 0xfa, 0x6c, 0xbd, + 0xed, 0x74, 0x42, 0x3a, 0xbd, 0xd5, 0x43, 0x8b, 0xfc, 0x1c, 0x2c, 0x61, 0xd4, 0x49, 0x02, 0x62, + 0x04, 0x8b, 0x1d, 0x0e, 0x77, 0xe8, 0x8b, 0x7f, 0x30, 0x28, 0x46, 0x53, 0x8f, 0x64, 0x60, 0xee, + 0x72, 0x99, 0xc3, 0xe1, 0xd0, 0x6c, 0x8a, 0xfa, 0x8e, 0x1c, 0xe8, 0x85, 0xeb, 0x3a, 0xa4, 0xfd, + 0x41, 0xfb, 0xcd, 0xe1, 0xbb, 0x23, 0x08, 0x00, 0xcb, 0x85, 0x9e, 0x2b, 0xaa, 0x97, 0x4b, 0x82, + 0xd8, 0x06, 0x61, 0xdb, 0xd0, 0x05, 0xa0, 0x0b, 0x51, 0x4d, 0x49, 0x96, 0xe8, 0x84, 0x7a, 0x11, + 0x0a, 0x30, 0xfa, 0x12, 0x46, 0x12, 0x12, 0x82, 0x0e, 0xc3, 0xaa, 0xf6, 0x43, 0x04, 0x77, 0x3b, + 0x6a, 0xff, 0x91, 0x20, 0xbc, 0x88, 0xd5, 0x58, 0x90, 0xa9, 0x6e, 0xdd, 0x31, 0xa4, 0x7a, 0xa4, + 0x79, 0x4e, 0x5e, 0xc7, 0x6c, 0xe0, 0xcd, 0xb2, 0x1b, 0x87, 0x8c, 0x57, 0xd0, 0x3e, 0x6e, 0xd1, + 0x93, 0xa0, 0x3e, 0xb4, 0x04, 0x0d, 0x06, 0xfa, 0x78, 0xff, 0xce, 0x37, 0xb7, 0x08, 0x68, 0xc5, + 0x21, 0x77, 0xbb, 0x74, 0x30, 0xeb, 0xb4, 0xe7, 0xd8, 0xd8, 0xca, 0x54, 0xca, 0xcb, 0x49, 0x73, + 0x4e, 0xd1, 0x43, 0x5d, 0x87, 0x32, 0x76, 0x9a, 0xed, 0xd2, 0x81, 0xa5, 0x88, 0x07, 0x2a, 0xe2, + 0x81, 0x1d, 0xf1, 0xa0, 0x1c, 0xf1, 0x40, 0x43, 0x9c, 0xa8, 0x88, 0x13, 0x3b, 0xe2, 0xa4, 0x1c, + 0x71, 0x42, 0x11, 0x4b, 0xb7, 0x18, 0x94, 0x75, 0xa9, 0xe4, 0x76, 0xad, 0xb4, 0x72, 0x3d, 0x5b, + 0x8f, 0x9b, 0xb6, 0x5c, 0xd1, 0x53, 0xb5, 0x46, 0x7f, 0xdc, 0xfa, 0x85, 0xfe, 0x11, 0xb5, 0x8c, + 0x7b, 0xe8, 0x10, 0xd5, 0xb7, 0x5f, 0x60, 0x54, 0x69, 0xbd, 0x83, 0x07, 0x50, 0x38, 0x94, 0xe0, + 0x76, 0xb0, 0x8c, 0x99, 0x42, 0x7c, 0x18, 0xf4, 0x90, 0x02, 0xd6, 0x87, 0x55, 0x43, 0x64, 0xb2, + 0x86, 0xea, 0x15, 0x6d, 0xa9, 0xa8, 0x59, 0x3f, 0x31, 0xe0, 0xde, 0x7b, 0x33, 0x9f, 0xa1, 0x37, + 0x13, 0x73, 0xe9, 0x46, 0xaa, 0x97, 0xc6, 0x93, 0x9b, 0x69, 0x5e, 0x9b, 0x6b, 0x5b, 0x05, 0x4e, + 0x8b, 0xb6, 0xe1, 0xa7, 0xbd, 0xbb, 0xf4, 0xe5, 0x9c, 0xb2, 0x28, 0x53, 0x61, 0xe9, 0x0d, 0x92, + 0xfe, 0x20, 0xe5, 0x77, 0xb6, 0x64, 0x90, 0xd7, 0xef, 0x67, 0x7d, 0x08, 0x1d, 0x9e, 0xe4, 0xdc, + 0x46, 0x16, 0x5d, 0x7d, 0xad, 0x8e, 0x7f, 0xcb, 0x8f, 0xb9, 0x80, 0x97, 0x86, 0xe1, 0x8e, 0x60, + 0x0f, 0xb2, 0xf6, 0xf7, 0xbf, 0xd7, 0x98, 0xa6, 0x1a, 0x81, 0xa2, 0x2a, 0x25, 0xdc, 0x22, 0x08, + 0xa2, 0x44, 0x1f, 0xfc, 0x44, 0xd6, 0xe5, 0x83, 0x0f, 0xe4, 0x85, 0x07, 0x79, 0x3c, 0xfd, 0x5b, + 0x4f, 0x53, 0x32, 0x76, 0x72, 0xe4, 0x64, 0x37, 0x07, 0x4e, 0x68, 0x2d, 0x4c, 0x75, 0xb0, 0x18, + 0x33, 0x15, 0xad, 0x91, 0xc3, 0x87, 0xb0, 0x46, 0xe0, 0xca, 0xe2, 0x6b, 0x31, 0x41, 0x58, 0xb7, + 0x36, 0xe7, 0x03, 0xae, 0xd5, 0xdb, 0xb4, 0x79, 0x8c, 0x19, 0x87, 0x95, 0x83, 0xa6, 0xf8, 0xf4, + 0xd7, 0xa1, 0x5b, 0xd0, 0xeb, 0x69, 0x5e, 0x9b, 0x3c, 0x2d, 0xb2, 0x7b, 0x37, 0xff, 0x36, 0x5a, + 0xe7, 0xe3, 0xaa, 0x8f, 0xbb, 0xd2, 0x01, 0x5f, 0xf7, 0xbe, 0x02, 0x1e, 0xa8, 0xf5, 0xba, 0x94, + 0x75, 0x14, 0xaa, 0xe9, 0x45, 0xfb, 0xdd, 0x88, 0xfd, 0x6e, 0xc4, 0xd6, 0xbb, 0x11, 0xf4, 0x71, + 0xa0, 0x25, 0x7d, 0xae, 0xc7, 0xbe, 0x21, 0x51, 0xd8, 0xb7, 0xa0, 0x25, 0x3c, 0x4d, 0x5e, 0xed, + 0xc3, 0xd1, 0x18, 0x8f, 0x81, 0x56, 0x8d, 0x37, 0xa3, 0xf4, 0x93, 0x2d, 0xe8, 0xcc, 0x43, 0x05, + 0x8c, 0xa9, 0xd4, 0xe5, 0xfd, 0xd1, 0x04, 0x96, 0xe1, 0x6c, 0x1a, 0x56, 0x8b, 0x6c, 0x41, 0x89, + 0x7e, 0x88, 0x31, 0x91, 0xc3, 0x3a, 0x90, 0x80, 0x57, 0xb3, 0xc5, 0x68, 0x8c, 0x60, 0x21, 0x98, + 0x99, 0x4c, 0x19, 0xbd, 0x38, 0x8e, 0x8d, 0x0c, 0x47, 0xca, 0x40, 0x3a, 0x39, 0x68, 0xc3, 0x81, + 0x92, 0xc4, 0xce, 0x02, 0x2b, 0xa4, 0x06, 0xef, 0xda, 0xef, 0x71, 0xf4, 0x2e, 0x8c, 0xa4, 0x4e, + 0x2b, 0x2a, 0x79, 0x55, 0x49, 0x7b, 0x39, 0x4e, 0x09, 0x5d, 0x55, 0x45, 0x17, 0xb0, 0x77, 0xb3, + 0xce, 0x3a, 0xb7, 0x19, 0x12, 0xce, 0x85, 0xe7, 0x55, 0xe2, 0x25, 0x4e, 0x27, 0xdf, 0x48, 0x99, + 0x3d, 0x1d, 0xa7, 0xd7, 0xa0, 0x7f, 0x4e, 0x1d, 0x1a, 0xe9, 0x19, 0x09, 0x01, 0x9f, 0x2e, 0x3b, + 0xa3, 0x78, 0xc1, 0x42, 0x6a, 0xe0, 0x50, 0xbb, 0x45, 0xbe, 0x22, 0x12, 0xcc, 0xc3, 0x01, 0xe2, + 0xf8, 0x03, 0x54, 0x38, 0x10, 0xe4, 0xbc, 0x8e, 0xff, 0x0c, 0xe8, 0xe3, 0x55, 0xf8, 0x23, 0x21, + 0x1f, 0xe4, 0x5f, 0x37, 0x40, 0xda, 0x3e, 0x52, 0xcd, 0x0a, 0xef, 0xb1, 0x94, 0x0f, 0x16, 0xd6, + 0xf4, 0x25, 0xa2, 0xa1, 0x4f, 0xea, 0xd8, 0x52, 0x68, 0xd0, 0x82, 0xc8, 0x94, 0xe1, 0x3f, 0x57, + 0x58, 0xf5, 0x65, 0x6a, 0x73, 0x62, 0x2d, 0xdb, 0xb2, 0x15, 0xe9, 0x59, 0x8b, 0xac, 0xad, 0xad, + 0x5f, 0x85, 0xd2, 0x96, 0x52, 0x24, 0x35, 0x14, 0x91, 0xf3, 0x2f, 0x2b, 0x50, 0xa3, 0x62, 0x1c, + 0x54, 0x21, 0xc2, 0x4c, 0xff, 0xb0, 0xa4, 0xb7, 0xcc, 0x25, 0x46, 0x15, 0xc8, 0x33, 0x97, 0x4c, + 0x97, 0xf1, 0x60, 0x90, 0xe2, 0xb8, 0x1b, 0x30, 0xa3, 0x81, 0x45, 0x6b, 0xff, 0xa8, 0x75, 0xb0, + 0x01, 0xda, 0x6a, 0x1e, 0x21, 0xeb, 0x93, 0x27, 0x1e, 0x35, 0x8f, 0x71, 0xe2, 0xe1, 0x31, 0x4a, + 0x45, 0x7f, 0xa8, 0x99, 0x9d, 0xce, 0x47, 0xd7, 0xd4, 0xba, 0xee, 0xd5, 0x2f, 0xd1, 0x7f, 0x23, + 0xb7, 0xe1, 0xc4, 0xf5, 0x3e, 0xfa, 0x6f, 0xe0, 0xfa, 0xce, 0xa0, 0x3e, 0x44, 0xff, 0x91, 0xb4, + 0x04, 0xfd, 0xd7, 0x73, 0xdd, 0xa0, 0x06, 0x76, 0x05, 0xaa, 0xc3, 0x77, 0x08, 0xf2, 0x06, 0x9f, + 0x1e, 0x10, 0x67, 0x42, 0x10, 0x54, 0x6f, 0xbf, 0x6f, 0x22, 0x96, 0xed, 0x34, 0x08, 0x98, 0x1e, + 0x8a, 0x0b, 0xdb, 0x12, 0x58, 0xf8, 0x60, 0x22, 0x9a, 0x4b, 0xb8, 0x0b, 0x00, 0xb1, 0x5e, 0x7c, + 0xf2, 0xbd, 0xe2, 0xdf, 0x2c, 0xfe, 0x9a, 0x30, 0xc7, 0x1e, 0x61, 0xe5, 0x7b, 0x22, 0x69, 0x4b, + 0x84, 0xa3, 0x49, 0x36, 0x96, 0x2f, 0x78, 0xeb, 0x25, 0xdc, 0x18, 0x55, 0x18, 0x4f, 0xa5, 0xb5, + 0x91, 0xa5, 0x63, 0x85, 0x56, 0xdf, 0x65, 0x18, 0xc6, 0xfd, 0xec, 0x46, 0x4f, 0x05, 0xa1, 0x6b, + 0x04, 0x8f, 0x7b, 0x10, 0x11, 0x46, 0x04, 0x01, 0x3c, 0x3f, 0xab, 0x1d, 0x36, 0xdb, 0x47, 0xed, + 0xe3, 0xf7, 0x9d, 0x37, 0xc7, 0x87, 0xc7, 0xef, 0xde, 0xbf, 0x7d, 0x7f, 0x78, 0x60, 0x08, 0x30, + 0x04, 0xe6, 0xbd, 0x75, 0x99, 0x95, 0x39, 0xd2, 0x21, 0x0f, 0xfe, 0x21, 0xb3, 0x13, 0xe2, 0x3b, + 0xba, 0x72, 0x80, 0x47, 0xbc, 0x62, 0x7c, 0x26, 0x01, 0x79, 0x7a, 0xd9, 0x02, 0xc7, 0x98, 0x8d, + 0xa7, 0x0b, 0xc7, 0x11, 0x4d, 0xfe, 0xab, 0xf5, 0xbd, 0x21, 0x7d, 0xb5, 0xbf, 0xbb, 0x1e, 0xb6, + 0xa4, 0xa9, 0x5a, 0xe1, 0xd6, 0xd5, 0x4c, 0x8e, 0x79, 0x9c, 0xcd, 0xd2, 0x08, 0x49, 0xdc, 0x29, + 0x82, 0xee, 0x1c, 0x7b, 0xf4, 0xa8, 0x38, 0xa6, 0xc8, 0x0d, 0xa4, 0x7a, 0xf9, 0x39, 0x71, 0x1c, + 0xfa, 0x26, 0xa2, 0xfc, 0x4b, 0x6c, 0x78, 0x34, 0xc9, 0x30, 0x06, 0xca, 0xc4, 0x7e, 0x83, 0xe6, + 0xba, 0x68, 0xda, 0x9d, 0x9f, 0xe1, 0xfb, 0x2e, 0x2c, 0x8f, 0xfb, 0x8a, 0xc0, 0xcb, 0xf3, 0x41, + 0x6e, 0x23, 0xb7, 0xc5, 0x23, 0x3a, 0x5e, 0xdc, 0x1f, 0x18, 0xdf, 0x8e, 0x26, 0x57, 0x38, 0xf4, + 0x31, 0x49, 0x5f, 0xd5, 0xcf, 0xcf, 0x42, 0xc9, 0xdc, 0x69, 0x37, 0xdf, 0xbd, 0x3d, 0x6e, 0x88, + 0x38, 0x87, 0xed, 0xe6, 0xdb, 0x63, 0x9a, 0x8f, 0x26, 0x29, 0x79, 0xaf, 0x14, 0xe2, 0x29, 0xf1, + 0x52, 0x24, 0xd0, 0xe5, 0x05, 0x6e, 0x3a, 0x2f, 0x86, 0x9b, 0x02, 0xf2, 0x02, 0x8d, 0x03, 0x9a, + 0xec, 0xd8, 0x6b, 0x8d, 0x7b, 0x87, 0x8c, 0x44, 0x20, 0x52, 0x19, 0x52, 0x92, 0xe1, 0x7a, 0xec, + 0x1b, 0x62, 0x06, 0x43, 0x01, 0x46, 0x36, 0x66, 0x18, 0x3c, 0x5e, 0x52, 0x85, 0x6c, 0x93, 0x19, + 0x67, 0xd2, 0xcd, 0x68, 0x3c, 0x50, 0x24, 0x05, 0x14, 0x2f, 0xf2, 0x8b, 0x7a, 0x36, 0x44, 0xb3, + 0x3a, 0x45, 0xe7, 0x0e, 0xb0, 0x30, 0x89, 0x28, 0x03, 0x3a, 0xbe, 0x43, 0xc6, 0xa6, 0x4e, 0xfb, + 0xcb, 0x0d, 0xce, 0xcf, 0xb0, 0x2c, 0x11, 0xdc, 0x44, 0x42, 0x54, 0x43, 0x21, 0x5a, 0x33, 0x79, + 0x19, 0x8c, 0xcc, 0x04, 0x5f, 0x62, 0x7e, 0x1f, 0x03, 0x21, 0x55, 0x05, 0x71, 0xb2, 0x4c, 0x7c, + 0x39, 0x51, 0x8a, 0x1c, 0x92, 0x5b, 0x48, 0x58, 0x51, 0xaa, 0xb8, 0x19, 0xbb, 0x75, 0xe9, 0xf3, + 0x7e, 0xc2, 0x8d, 0x4f, 0xc9, 0x93, 0x2f, 0xbf, 0x9d, 0x9d, 0xfc, 0x72, 0x76, 0x72, 0x71, 0xf6, + 0xe5, 0xe7, 0x9a, 0xe5, 0x81, 0x00, 0x44, 0x30, 0x87, 0xc7, 0x2d, 0xc3, 0x41, 0x9f, 0x8f, 0xdf, + 0xbd, 0x3d, 0x6c, 0xb5, 0xdf, 0x1c, 0x14, 0x76, 0xf8, 0xc0, 0x6a, 0x22, 0x0e, 0xab, 0xe2, 0xee, + 0x1f, 0x0e, 0x92, 0x5e, 0xae, 0xe0, 0x16, 0x43, 0xfb, 0x42, 0xb8, 0x28, 0x4d, 0x3a, 0xa1, 0x16, + 0xea, 0xef, 0x1a, 0x6a, 0xa2, 0x8e, 0x52, 0xa0, 0xa5, 0xe2, 0x58, 0x40, 0x9d, 0x42, 0xa4, 0xa8, + 0x41, 0x3c, 0x99, 0xc4, 0x2c, 0xf4, 0x93, 0x21, 0x60, 0x2a, 0x58, 0x53, 0xd3, 0x74, 0x91, 0x5d, + 0xc6, 0xf3, 0x17, 0x17, 0x46, 0x67, 0xff, 0xd4, 0xd7, 0x16, 0xc7, 0x6c, 0x07, 0xf1, 0xac, 0xe4, + 0xa9, 0x2c, 0x96, 0x5b, 0x16, 0xb7, 0x9a, 0xc1, 0xac, 0x8b, 0x5c, 0x2d, 0xc3, 0x95, 0x75, 0x19, + 0x7e, 0x5d, 0xd6, 0xd2, 0x24, 0x9c, 0x67, 0xef, 0x30, 0x9c, 0x5d, 0xde, 0x29, 0x1c, 0xa4, 0x84, + 0x84, 0x92, 0x0e, 0x59, 0xdb, 0x1b, 0x95, 0xba, 0x42, 0xed, 0x87, 0xe7, 0x17, 0x72, 0xe9, 0xb5, + 0x3f, 0x58, 0xc5, 0x99, 0x5e, 0x1d, 0x18, 0x96, 0x6c, 0x20, 0x84, 0x65, 0xf9, 0xf2, 0x9c, 0xb0, + 0x84, 0xf0, 0x16, 0x68, 0x36, 0xe4, 0x79, 0xb9, 0x45, 0xe4, 0xc5, 0x67, 0x43, 0x8f, 0xe0, 0x0c, + 0x5f, 0xcc, 0x05, 0x63, 0x7f, 0xd0, 0xd2, 0x9b, 0xb0, 0xbb, 0xda, 0x06, 0x5b, 0x3f, 0xb0, 0x4e, + 0x28, 0xef, 0x01, 0xd6, 0x7c, 0x8d, 0xcf, 0x95, 0xf0, 0xa2, 0x51, 0xcc, 0x5e, 0x8c, 0x68, 0xb4, + 0x3b, 0xef, 0x90, 0x7a, 0x4f, 0x15, 0xa3, 0x2e, 0xdf, 0x4e, 0x89, 0x48, 0x60, 0x73, 0xf2, 0x1e, + 0x04, 0x0e, 0x5a, 0x09, 0x8a, 0x4a, 0x28, 0x2d, 0x51, 0x11, 0x8f, 0x25, 0x4e, 0x80, 0xc0, 0x15, + 0xe0, 0xd6, 0xe9, 0xd7, 0x8d, 0xf7, 0xe6, 0x88, 0xc6, 0x43, 0x17, 0x1e, 0x56, 0x79, 0xd1, 0x06, + 0xdf, 0xad, 0x32, 0x7b, 0xf9, 0x86, 0xb0, 0x04, 0x03, 0xfe, 0x5b, 0xfa, 0x9b, 0x6e, 0x43, 0x86, + 0x7c, 0x7c, 0xd9, 0x0f, 0xd0, 0x1b, 0x98, 0xb1, 0x1b, 0x8f, 0x2f, 0x49, 0xa6, 0xc8, 0xa1, 0xa3, + 0x01, 0xc4, 0x7b, 0x74, 0x40, 0x98, 0x56, 0x0b, 0xe9, 0x0c, 0x4b, 0xdd, 0x61, 0xbf, 0xb8, 0x1e, + 0xac, 0xe8, 0x2c, 0x60, 0xa5, 0x72, 0xe5, 0x2e, 0xbb, 0xca, 0x95, 0xb2, 0xbc, 0x5e, 0xaf, 0x88, + 0xa5, 0x83, 0x5f, 0xac, 0x00, 0xc5, 0xa8, 0xee, 0x08, 0xfa, 0xa8, 0x6e, 0x4e, 0x9e, 0xb3, 0x90, + 0x2b, 0x72, 0xd5, 0x4e, 0xc1, 0x97, 0x44, 0x49, 0x75, 0x9e, 0x88, 0x9d, 0x49, 0x34, 0x08, 0x4d, + 0xae, 0x61, 0x45, 0x5a, 0x1a, 0x40, 0x2d, 0x3f, 0x27, 0xee, 0x4b, 0xa4, 0x90, 0x5e, 0x69, 0x75, + 0x90, 0x5e, 0xe9, 0x44, 0xe4, 0xaf, 0x5e, 0x8d, 0xc7, 0x36, 0x05, 0x91, 0x32, 0x9d, 0x43, 0x20, + 0xeb, 0xc6, 0x95, 0x7f, 0x05, 0xaf, 0xb6, 0x6b, 0x4f, 0x7a, 0x31, 0xc6, 0x52, 0x6d, 0x4b, 0xa0, + 0x3f, 0xa0, 0xca, 0x15, 0xdb, 0x03, 0x2d, 0x3b, 0x63, 0x2a, 0x5e, 0x38, 0xef, 0x28, 0xc5, 0x70, + 0xff, 0x15, 0x2a, 0x33, 0xc6, 0x9b, 0xc4, 0x6f, 0x6a, 0xa1, 0x2e, 0x93, 0x83, 0x81, 0xb2, 0x7b, + 0xb6, 0xe4, 0xb6, 0xac, 0xb5, 0x94, 0xa9, 0x48, 0xa1, 0xd2, 0x42, 0xe8, 0x00, 0xcf, 0xa4, 0x27, + 0x82, 0x2d, 0x2d, 0xa9, 0x7b, 0xd1, 0x7a, 0x1a, 0x83, 0x35, 0x04, 0x85, 0x4c, 0xad, 0x24, 0x0e, + 0x12, 0xc2, 0x14, 0x3e, 0xe6, 0xe2, 0xa7, 0x0b, 0x8f, 0xf7, 0x82, 0xde, 0xab, 0x2a, 0x57, 0xd1, + 0xcd, 0xea, 0xbc, 0x51, 0x71, 0x7f, 0xdc, 0x10, 0x7e, 0xbb, 0x79, 0x39, 0xc9, 0x74, 0x05, 0x9d, + 0xb4, 0xdd, 0xf5, 0x58, 0xdf, 0x34, 0x17, 0xa1, 0x20, 0xa1, 0x13, 0xe1, 0x77, 0x7f, 0xea, 0x66, + 0xdb, 0x0d, 0x0a, 0xc9, 0x7d, 0x24, 0x5f, 0x5c, 0x27, 0x76, 0xe9, 0x04, 0xf5, 0x17, 0x54, 0xd7, + 0x70, 0x38, 0xfa, 0xbc, 0x81, 0x11, 0xbb, 0xbe, 0xa8, 0x10, 0x47, 0x4e, 0x75, 0x03, 0x9c, 0x6e, + 0x31, 0x5e, 0x1f, 0x21, 0x54, 0x16, 0xb7, 0x3a, 0x7f, 0x3d, 0xf9, 0xb3, 0xfb, 0xcb, 0xd9, 0x97, + 0xd3, 0xee, 0xa7, 0xb3, 0x8b, 0xdf, 0x4e, 0xbe, 0x7c, 0x3c, 0xad, 0x1d, 0x76, 0xde, 0xbe, 0x79, + 0x2b, 0xd9, 0xa5, 0x7b, 0x3b, 0xb6, 0xba, 0x1d, 0x8b, 0x24, 0xe7, 0x60, 0x9e, 0x2e, 0xac, 0x31, + 0x4c, 0xf6, 0x16, 0xe3, 0xde, 0x62, 0x7c, 0xad, 0x16, 0xe3, 0xde, 0x86, 0xdb, 0xdb, 0x70, 0xcf, + 0xdc, 0x86, 0x63, 0xe2, 0xb9, 0xaa, 0x19, 0x17, 0x14, 0x56, 0xc7, 0xbd, 0x61, 0xb7, 0x37, 0xec, + 0xf6, 0x86, 0xdd, 0x13, 0x19, 0x76, 0x2f, 0xc8, 0xf2, 0xaa, 0xbc, 0x6f, 0xbc, 0xbd, 0x4d, 0xb6, + 0x5e, 0x09, 0xad, 0x72, 0x62, 0x73, 0x6f, 0x7a, 0xe9, 0xa6, 0x97, 0xe5, 0x79, 0x33, 0xba, 0x51, + 0x0e, 0xec, 0xaa, 0x76, 0xb3, 0xfd, 0x99, 0xb3, 0xc7, 0xb1, 0xd8, 0x8a, 0xf6, 0x15, 0xcb, 0x51, + 0x56, 0xaa, 0xee, 0xc5, 0xc7, 0x93, 0x5f, 0x4e, 0x6b, 0x9d, 0x2d, 0x2c, 0xb9, 0x87, 0xb6, 0xd7, + 0xec, 0x16, 0x59, 0xb9, 0x45, 0x77, 0x1f, 0x7b, 0x4d, 0xec, 0x2a, 0x96, 0x4d, 0xa2, 0xbd, 0x99, + 0xf6, 0x70, 0x66, 0xda, 0x33, 0xb0, 0x8a, 0x9e, 0x9d, 0xa5, 0xb8, 0x63, 0x33, 0x6d, 0x7f, 0x09, + 0xf5, 0x19, 0x5d, 0x42, 0x7d, 0xe5, 0xe6, 0xf0, 0xd3, 0x9a, 0x9f, 0xcf, 0xcd, 0x18, 0xdf, 0x95, + 0x39, 0xfc, 0xff, 0xe6, 0x5a, 0xf0, 0xfd, 0x4d, 0x7e, 0x06, 0xb7, 0xd9, 0xe6, 0xad, 0x41, 0x87, + 0xda, 0xdb, 0xfc, 0x7b, 0x9b, 0x7f, 0x6f, 0xf3, 0x3f, 0x84, 0xcd, 0x2f, 0xa6, 0x62, 0x2c, 0x2b, + 0xe8, 0xe5, 0xbe, 0x80, 0x6d, 0x2e, 0xa7, 0x2a, 0xf2, 0x46, 0x0f, 0xe1, 0xb2, 0xd6, 0x26, 0xdf, + 0x9d, 0xa1, 0xf1, 0x5a, 0xee, 0x86, 0xbe, 0xfc, 0x9d, 0xf2, 0xf5, 0xae, 0x92, 0x67, 0x74, 0xc9, + 0xf4, 0x09, 0x5d, 0x39, 0xfb, 0x10, 0xc7, 0xaf, 0xeb, 0xe1, 0x13, 0xb9, 0xab, 0xe5, 0xf6, 0xa9, + 0x6d, 0x6e, 0x2e, 0x3d, 0xde, 0x6b, 0x81, 0x1a, 0x2c, 0x58, 0x03, 0x5c, 0x99, 0x70, 0x26, 0x06, + 0x9c, 0x88, 0x6a, 0x8f, 0xf6, 0x77, 0x19, 0x46, 0xa0, 0x38, 0x7c, 0x51, 0xfe, 0x43, 0x82, 0x6d, + 0x89, 0x3a, 0x92, 0x5c, 0x75, 0xe6, 0x0b, 0x44, 0xa0, 0xf6, 0x73, 0x73, 0xa9, 0xc2, 0x27, 0xe5, + 0xf0, 0x89, 0x0a, 0xbf, 0xea, 0xe2, 0x17, 0x93, 0xeb, 0xbc, 0x27, 0x90, 0x82, 0x43, 0x6f, 0x74, + 0x71, 0xfa, 0x30, 0x4d, 0x8e, 0x56, 0xeb, 0xaa, 0xde, 0xa1, 0xcf, 0xbe, 0xb8, 0x3a, 0x41, 0x2b, + 0x81, 0x3c, 0xd9, 0x06, 0x79, 0x62, 0x47, 0x9e, 0x08, 0xc6, 0xc0, 0x51, 0x4f, 0x36, 0xbf, 0x78, + 0x8e, 0x39, 0x08, 0xf5, 0xaa, 0x8f, 0x5a, 0xee, 0x4a, 0xb8, 0x92, 0x2d, 0xae, 0x8d, 0x53, 0x5c, + 0x09, 0xc2, 0x95, 0xb8, 0x8a, 0xc7, 0x17, 0x70, 0x19, 0xaf, 0x8e, 0xa3, 0x4a, 0x7d, 0x73, 0x46, + 0xe2, 0x9a, 0xaf, 0x8c, 0x13, 0x1f, 0xf0, 0x03, 0xbe, 0x3f, 0xf1, 0x82, 0x3d, 0xc0, 0x95, 0x4e, + 0xec, 0xd0, 0xc1, 0x22, 0xcf, 0x56, 0xc7, 0x05, 0x05, 0x0f, 0xf5, 0x7e, 0x77, 0x25, 0xa5, 0x9b, + 0x4a, 0x25, 0x96, 0x52, 0xc9, 0x23, 0x9d, 0x0e, 0xa2, 0xa9, 0x50, 0x49, 0x6c, 0x4a, 0x4c, 0xb6, + 0x51, 0x0a, 0xf7, 0xf7, 0x5d, 0xf6, 0xa7, 0x97, 0xf6, 0xa7, 0x97, 0xca, 0xdd, 0xe2, 0x6c, 0xc8, + 0x0c, 0x3e, 0xb3, 0x87, 0x70, 0x99, 0x63, 0x47, 0x51, 0x09, 0x95, 0x22, 0xdf, 0xda, 0x57, 0x02, + 0xc4, 0xc4, 0x5f, 0x52, 0x6e, 0x59, 0x6f, 0xaa, 0x60, 0xfb, 0xcb, 0x3b, 0xfb, 0x83, 0x5f, 0xcf, + 0xe4, 0xe0, 0xd7, 0xee, 0x7c, 0xdb, 0xd2, 0x54, 0x14, 0x3f, 0x0d, 0x35, 0x8b, 0x4c, 0x5f, 0x9d, + 0x9f, 0xa6, 0x26, 0xcb, 0x98, 0x8c, 0x93, 0x6c, 0xef, 0x82, 0xde, 0xbb, 0xa0, 0xf7, 0x2e, 0xe8, + 0x57, 0xe8, 0x82, 0xc6, 0xaa, 0x7a, 0x44, 0x65, 0x06, 0x9f, 0x97, 0x9e, 0x6e, 0x7d, 0x34, 0x97, + 0x81, 0x24, 0x50, 0xf8, 0xf8, 0x15, 0xc0, 0x56, 0x75, 0x6e, 0x98, 0xb8, 0x14, 0x7b, 0xb2, 0x16, + 0x7b, 0x52, 0x0d, 0x7b, 0x22, 0x61, 0x87, 0xe8, 0x66, 0xd5, 0xdc, 0xe4, 0xeb, 0x43, 0x73, 0x2d, + 0xfa, 0x97, 0xb8, 0x5b, 0x8b, 0x31, 0x96, 0x90, 0xc5, 0xf6, 0xcc, 0xac, 0xa0, 0xfd, 0x2d, 0xae, + 0xf2, 0x75, 0x78, 0x77, 0x7a, 0xf0, 0xe3, 0x2a, 0xb1, 0x2f, 0xf1, 0x42, 0x99, 0x11, 0x43, 0xc9, + 0x41, 0x80, 0x62, 0x8f, 0x97, 0x76, 0xf8, 0x06, 0xea, 0xca, 0x0b, 0xf4, 0x8f, 0x22, 0x21, 0x04, + 0xb9, 0xdd, 0xd8, 0x18, 0x8d, 0x08, 0x8b, 0x12, 0xb7, 0x19, 0x6b, 0xc0, 0x89, 0x15, 0x38, 0x29, + 0x00, 0x63, 0x57, 0x1e, 0xaf, 0xc5, 0xe7, 0x28, 0x7c, 0x2c, 0xe7, 0xdc, 0x90, 0x38, 0xe6, 0x22, + 0xe5, 0x7d, 0xd9, 0xe3, 0x86, 0x90, 0x8e, 0xb2, 0x84, 0x26, 0x01, 0x85, 0x4d, 0x39, 0x14, 0xed, + 0xe3, 0x1f, 0xff, 0xac, 0x74, 0xc2, 0x32, 0x1f, 0xa3, 0x15, 0x64, 0x2e, 0x3f, 0x46, 0xc1, 0x65, + 0x3e, 0x5e, 0x51, 0x2c, 0x99, 0xc9, 0xd5, 0xe5, 0x65, 0x3a, 0x2f, 0x7b, 0x78, 0x76, 0xc3, 0x30, + 0x5c, 0x2d, 0x43, 0x5a, 0x7b, 0xdb, 0xd8, 0x5c, 0xad, 0xc8, 0x71, 0xcc, 0xb1, 0x0b, 0x1b, 0x70, + 0xf2, 0x36, 0x50, 0xe9, 0xaf, 0xb9, 0x10, 0x65, 0x88, 0x94, 0x6c, 0x47, 0x24, 0x94, 0x1b, 0x3c, + 0x70, 0x2e, 0x77, 0x00, 0x84, 0x9f, 0x12, 0x5d, 0x25, 0x75, 0xae, 0xbc, 0x97, 0xdc, 0xcd, 0xad, + 0x31, 0x2d, 0xad, 0x4b, 0x6d, 0xcb, 0x9e, 0xd5, 0xae, 0xdc, 0x4d, 0x85, 0xd1, 0x99, 0x43, 0x0c, + 0x24, 0xa4, 0x4a, 0x2c, 0x20, 0x22, 0x77, 0x59, 0x36, 0x08, 0xcb, 0xe2, 0xc8, 0xc7, 0xa8, 0xdb, + 0x70, 0x38, 0x38, 0xfd, 0x7d, 0x13, 0xe1, 0x54, 0x9c, 0xe6, 0xf3, 0x78, 0x61, 0x7a, 0xff, 0x04, + 0x5e, 0x2a, 0x59, 0xcc, 0x46, 0xd3, 0xee, 0x0d, 0x8e, 0xc2, 0xab, 0x1d, 0x29, 0x17, 0x62, 0xb9, + 0x55, 0x9c, 0x98, 0x2d, 0x12, 0x54, 0xac, 0xb5, 0x26, 0x4c, 0x6c, 0x9b, 0x80, 0xb5, 0x49, 0x34, + 0x6e, 0x82, 0xac, 0x19, 0x13, 0xd5, 0x1f, 0x55, 0x41, 0x13, 0xe6, 0x83, 0x24, 0x12, 0x3f, 0x03, + 0x06, 0x16, 0xde, 0xf1, 0x42, 0x6d, 0xbd, 0x50, 0x5b, 0x14, 0x6a, 0x8b, 0x42, 0x6d, 0x28, 0xa4, + 0xf9, 0xfb, 0x09, 0x36, 0x9f, 0x46, 0x81, 0x65, 0xa3, 0x4f, 0x1f, 0x55, 0x6a, 0x22, 0x19, 0x21, + 0x45, 0x33, 0x85, 0x2e, 0xe1, 0x78, 0x01, 0x6d, 0x08, 0x5f, 0x38, 0x9a, 0x36, 0x44, 0x32, 0x47, + 0x1f, 0xbe, 0xda, 0x63, 0x10, 0xe1, 0xdf, 0xf5, 0x2d, 0x79, 0xb7, 0xcb, 0x95, 0x35, 0x6f, 0x75, + 0xbb, 0xe4, 0x71, 0xd1, 0xe2, 0xeb, 0x14, 0x49, 0x87, 0x34, 0x62, 0x2f, 0x10, 0xb1, 0x67, 0xa5, + 0xd8, 0x7b, 0x52, 0x6e, 0x70, 0x08, 0x61, 0x2c, 0x21, 0x42, 0xb8, 0x43, 0x61, 0x1b, 0xe8, 0x0b, + 0xc2, 0x77, 0x15, 0x87, 0x1f, 0x08, 0x86, 0x0a, 0xf1, 0xec, 0xf1, 0x0a, 0xc3, 0x4f, 0xa6, 0x0f, + 0x19, 0x7a, 0x60, 0x28, 0xb0, 0xaf, 0x49, 0x03, 0x75, 0x56, 0xf4, 0xd7, 0x26, 0xb8, 0x0c, 0x11, + 0xfa, 0x6d, 0xc1, 0x03, 0x55, 0xf8, 0x15, 0x52, 0x34, 0x09, 0x8b, 0x25, 0x05, 0x89, 0x17, 0xc6, + 0x88, 0xf4, 0x79, 0x35, 0x3e, 0x6e, 0x3b, 0x1d, 0x3e, 0x9f, 0x85, 0xf8, 0xba, 0x9f, 0xfc, 0x45, + 0xbd, 0xb4, 0xc8, 0xe9, 0x94, 0x39, 0x3f, 0x8b, 0x0a, 0xc1, 0xf6, 0x42, 0xe3, 0x96, 0x09, 0xb5, + 0x96, 0xcd, 0x5b, 0x26, 0x4a, 0xea, 0x21, 0x94, 0xe0, 0x76, 0x92, 0x2a, 0x73, 0x99, 0x1b, 0x01, + 0x33, 0xa6, 0x2e, 0x84, 0x92, 0x2c, 0x1b, 0x83, 0x90, 0x59, 0x90, 0x8d, 0x36, 0x08, 0xf4, 0xd8, + 0xc5, 0xc4, 0xc6, 0x92, 0xa4, 0xd7, 0x80, 0x2e, 0xd3, 0x18, 0xcb, 0xd2, 0x02, 0x9c, 0xfa, 0x02, + 0x1f, 0x86, 0x2d, 0xcb, 0xb4, 0x64, 0xf5, 0xe2, 0x09, 0xe2, 0x41, 0x30, 0xe4, 0x20, 0xe8, 0x1a, + 0x92, 0xcc, 0xec, 0x1d, 0x04, 0x0b, 0xfc, 0x6c, 0x94, 0xf7, 0x86, 0x3a, 0xad, 0xf3, 0x2c, 0x8f, + 0xf3, 0xb4, 0xbb, 0x58, 0x4d, 0x92, 0x6c, 0x6c, 0x29, 0x48, 0x42, 0xcc, 0x69, 0xbb, 0x49, 0x8a, + 0x10, 0xef, 0x0d, 0x71, 0x04, 0xc6, 0x17, 0xb0, 0x7b, 0xb0, 0x66, 0x03, 0x8d, 0xa4, 0x8e, 0xe3, + 0x24, 0x45, 0x0b, 0xd7, 0x38, 0x9e, 0xa6, 0x16, 0x88, 0x01, 0x7b, 0xbd, 0x41, 0xcb, 0x16, 0x1c, + 0x00, 0x22, 0x58, 0x4f, 0xc6, 0x23, 0x40, 0xcc, 0xe5, 0x49, 0x3c, 0x0b, 0x2d, 0x47, 0xae, 0x8a, + 0xa6, 0x5d, 0xc1, 0xb0, 0x53, 0x58, 0xf4, 0x99, 0xbc, 0x3c, 0x2e, 0xf4, 0x98, 0x48, 0x9e, 0x95, + 0xfc, 0xa4, 0x09, 0x73, 0x93, 0xaa, 0xb9, 0xec, 0x9c, 0x0a, 0xd6, 0x3c, 0x84, 0x07, 0x90, 0x25, + 0x42, 0x87, 0xb0, 0x54, 0x04, 0x2a, 0xf3, 0xe5, 0x22, 0x1d, 0x4c, 0x20, 0xd8, 0x20, 0xe2, 0xbc, + 0x71, 0x1a, 0x35, 0xb4, 0x79, 0xfd, 0x57, 0xe7, 0x3b, 0x53, 0x54, 0xa1, 0x4f, 0x61, 0x01, 0xfb, + 0xc1, 0x32, 0x7d, 0xe1, 0x9d, 0x91, 0x1f, 0xec, 0xb3, 0x16, 0x75, 0x2a, 0xa6, 0x02, 0xc4, 0x20, + 0x21, 0xe8, 0xaf, 0xd6, 0x77, 0x9f, 0xfe, 0x6a, 0x7f, 0xf7, 0xd9, 0x04, 0x76, 0x03, 0x1c, 0xb7, + 0x38, 0xbc, 0xab, 0x41, 0x9f, 0xd5, 0xa0, 0xc6, 0xfb, 0x55, 0xc8, 0x2b, 0x2b, 0x22, 0x2e, 0x6b, + 0xca, 0x7a, 0xc4, 0x54, 0xaa, 0x50, 0x7c, 0x6a, 0x9a, 0xea, 0x2b, 0x3b, 0xcf, 0x46, 0xd3, 0x7c, + 0x5d, 0x08, 0x6d, 0x1a, 0x09, 0x99, 0x4b, 0x23, 0x24, 0x82, 0x86, 0x99, 0x90, 0x46, 0x91, 0x8a, + 0xad, 0xa9, 0x8e, 0x22, 0x83, 0x22, 0xd2, 0x25, 0xd2, 0xe7, 0x48, 0xed, 0xa7, 0x03, 0x2b, 0xe2, + 0xa0, 0x44, 0x04, 0xd6, 0x3e, 0x1c, 0x94, 0xe4, 0x06, 0x56, 0x9c, 0x0a, 0x6d, 0x92, 0x4b, 0x8b, + 0x92, 0x47, 0xcc, 0x32, 0xb0, 0x53, 0xc0, 0x85, 0xa9, 0xd2, 0x8e, 0x4d, 0x2f, 0xf0, 0x2c, 0x87, + 0xd0, 0x93, 0x5e, 0x54, 0x28, 0xcd, 0xce, 0x45, 0x21, 0x45, 0x80, 0x9d, 0x7f, 0xa2, 0x72, 0xa2, + 0xf6, 0x13, 0xe6, 0xd2, 0xa0, 0x73, 0x84, 0xbd, 0xac, 0x78, 0x24, 0x14, 0x56, 0xc7, 0xd2, 0x99, + 0xc8, 0x6a, 0xd0, 0xe4, 0x51, 0x4d, 0x21, 0xe1, 0x2f, 0x45, 0x7c, 0x33, 0x5d, 0x91, 0x4c, 0xad, + 0xf3, 0xb5, 0x83, 0x48, 0x62, 0x2f, 0xb7, 0x71, 0x48, 0x68, 0xfe, 0x2e, 0x4f, 0xac, 0x8f, 0xd7, + 0x72, 0x15, 0x14, 0x46, 0x10, 0x43, 0x26, 0x91, 0xa9, 0x22, 0x80, 0x37, 0xa6, 0xdf, 0x84, 0x7a, + 0x33, 0x70, 0xfc, 0x58, 0x07, 0xce, 0x4e, 0xe1, 0x03, 0x5a, 0xea, 0x42, 0xe3, 0xc3, 0xf1, 0x2b, + 0x38, 0xe3, 0x15, 0xde, 0xc9, 0x5d, 0x81, 0x67, 0x3b, 0xe2, 0xd5, 0x69, 0x84, 0xc3, 0x94, 0xca, + 0x32, 0xa0, 0xae, 0xe1, 0x57, 0xf9, 0x93, 0x14, 0xec, 0x21, 0xe9, 0x84, 0x83, 0xb3, 0x96, 0x17, + 0x04, 0x07, 0x72, 0x8d, 0x7d, 0xd2, 0x8e, 0x8b, 0xb0, 0x57, 0x99, 0xa3, 0xf1, 0xb1, 0x9f, 0x9e, + 0x93, 0xe3, 0xeb, 0xbf, 0x7a, 0x34, 0xd2, 0xaf, 0xec, 0x79, 0x06, 0xd9, 0x68, 0x5a, 0x5d, 0xf8, + 0x98, 0xc8, 0x90, 0xa8, 0x23, 0x95, 0x40, 0x35, 0x92, 0x1d, 0xa7, 0xad, 0x3e, 0xd4, 0x21, 0xad, + 0x15, 0x0e, 0xd4, 0x84, 0x9b, 0xba, 0xd6, 0x1e, 0x8f, 0x6f, 0x5c, 0x05, 0x87, 0x10, 0xad, 0x97, + 0xf3, 0xa5, 0x14, 0x7f, 0xfa, 0x9a, 0x4a, 0x65, 0xf4, 0x6f, 0x20, 0x2d, 0x50, 0x30, 0xfa, 0xf2, + 0x12, 0xc4, 0x96, 0x13, 0xfa, 0xe9, 0xa8, 0x3a, 0x14, 0x8f, 0x4e, 0x2e, 0x34, 0x85, 0x48, 0xce, + 0x47, 0x42, 0x14, 0xdb, 0x14, 0x10, 0x87, 0x57, 0xd1, 0x27, 0x6a, 0x1f, 0x1a, 0xaa, 0x7e, 0xa1, + 0x2e, 0x7c, 0xfc, 0xd9, 0x2a, 0x70, 0x93, 0x40, 0xec, 0x6c, 0x05, 0x69, 0xeb, 0x7b, 0x5d, 0x2a, + 0xea, 0x5a, 0x9d, 0xb7, 0xd4, 0x54, 0x0a, 0x9f, 0x24, 0x54, 0xd4, 0xe6, 0x6b, 0xfb, 0x3d, 0x9d, + 0x69, 0x12, 0x10, 0x71, 0x34, 0x51, 0x00, 0x4f, 0xab, 0xd7, 0xfa, 0x5e, 0x04, 0xfd, 0x4d, 0xfc, + 0x41, 0x2e, 0x39, 0x77, 0xb5, 0x57, 0xf9, 0x1f, 0x5e, 0xe5, 0xb7, 0x79, 0x8a, 0x47, 0xe3, 0x71, + 0xd9, 0xc9, 0x25, 0x91, 0x6f, 0x3f, 0xbe, 0x24, 0x60, 0x4c, 0x67, 0x98, 0xa4, 0xdc, 0x32, 0xe7, + 0xbf, 0x0a, 0x56, 0xf6, 0xf2, 0x53, 0x3c, 0xce, 0xca, 0x28, 0x16, 0xf9, 0x76, 0x8a, 0x05, 0x8c, + 0x89, 0x62, 0x29, 0xb7, 0x8c, 0x62, 0x15, 0xec, 0x45, 0x1f, 0x76, 0xc2, 0x4d, 0x29, 0x39, 0x37, + 0x23, 0xf2, 0xed, 0x8f, 0xb2, 0x72, 0x10, 0xe3, 0xc3, 0xac, 0x22, 0xb7, 0xf4, 0x61, 0x2e, 0x05, + 0x6c, 0x1d, 0xc1, 0xf6, 0x73, 0x6d, 0x3c, 0xbb, 0x9c, 0x5c, 0xdb, 0x09, 0x37, 0x91, 0xb9, 0x96, + 0x58, 0x65, 0x6f, 0xe2, 0x39, 0xda, 0x82, 0x8f, 0x69, 0xb2, 0x6f, 0xea, 0x3e, 0x30, 0x99, 0xf8, + 0xd5, 0x6c, 0x56, 0x90, 0xc2, 0x8a, 0xdb, 0xf5, 0x90, 0x26, 0xb6, 0x2b, 0x59, 0xab, 0x92, 0x94, + 0x13, 0x3f, 0x4d, 0x47, 0xac, 0x44, 0xae, 0xaf, 0xca, 0x3e, 0xd3, 0x61, 0x2b, 0x19, 0xd5, 0x56, + 0xf2, 0x4b, 0xfc, 0x34, 0xd1, 0x22, 0x72, 0x7d, 0x55, 0xaa, 0x99, 0x68, 0x91, 0x51, 0x6d, 0x2e, + 0x99, 0x76, 0x7e, 0x36, 0x4b, 0x12, 0x38, 0xe2, 0xa7, 0xe9, 0x2d, 0x5e, 0x9e, 0xe9, 0xab, 0x52, + 0xc8, 0xf8, 0x26, 0xaf, 0x84, 0x69, 0x1b, 0x51, 0xc2, 0x7f, 0xd9, 0x08, 0xa1, 0xa7, 0xe2, 0x24, + 0xe9, 0x62, 0x25, 0x83, 0x6e, 0x5d, 0x16, 0x65, 0xc4, 0xde, 0xab, 0xb1, 0xf7, 0x6a, 0xec, 0xbd, + 0x1a, 0x7b, 0xaf, 0xc6, 0xde, 0xab, 0xf1, 0x7a, 0xbc, 0x1a, 0xec, 0x44, 0xb0, 0x38, 0xf3, 0xa6, + 0x9c, 0x92, 0x23, 0x7c, 0xf0, 0xac, 0x1c, 0x1f, 0xe2, 0xb5, 0xa4, 0xf9, 0x2c, 0x1b, 0xc7, 0xd0, + 0xfa, 0x7b, 0x78, 0x42, 0xa8, 0x7e, 0x46, 0x4e, 0xb8, 0xa1, 0xb6, 0x35, 0x97, 0x70, 0xe7, 0x0a, + 0x5f, 0x1d, 0x23, 0x4a, 0x1a, 0xd9, 0x40, 0x94, 0x3a, 0xc8, 0x27, 0xcf, 0x80, 0xda, 0xea, 0x27, + 0xc1, 0xe4, 0xe8, 0xe5, 0xa7, 0x8b, 0x4f, 0x9f, 0xbb, 0xe7, 0x7f, 0xd6, 0xde, 0x49, 0xf7, 0xa1, + 0x4e, 0x3f, 0xfd, 0x7c, 0xda, 0xfd, 0xf9, 0xe4, 0xd7, 0x5f, 0x4f, 0x50, 0x6b, 0xdb, 0xad, 0x63, + 0xc3, 0x61, 0x98, 0x83, 0xa2, 0xd6, 0x0c, 0x8b, 0x71, 0x05, 0x3b, 0x78, 0xb7, 0x36, 0xec, 0x0e, + 0xed, 0xcf, 0x5d, 0x99, 0x90, 0x3b, 0xb5, 0xff, 0x1e, 0xc1, 0x7c, 0x33, 0x79, 0xf3, 0xcc, 0x26, + 0x8f, 0x7c, 0xda, 0xca, 0x62, 0xa5, 0xdd, 0xc3, 0x90, 0x29, 0xe5, 0xd2, 0xcd, 0xec, 0x90, 0x72, + 0x33, 0x64, 0x23, 0x33, 0xe2, 0x31, 0x4e, 0xdf, 0x49, 0xcc, 0xb3, 0x99, 0x3e, 0x5f, 0xc6, 0x19, + 0x9b, 0xa9, 0xe4, 0x20, 0x9e, 0xe9, 0xf0, 0x80, 0x62, 0x5d, 0x14, 0xe9, 0x74, 0x98, 0xf8, 0x65, + 0x75, 0xac, 0x0f, 0xb2, 0xc4, 0x95, 0x2c, 0x99, 0x59, 0xe3, 0x69, 0xa6, 0xd0, 0xb1, 0x2b, 0xea, + 0x34, 0x22, 0x68, 0x03, 0x19, 0x09, 0x69, 0x48, 0x65, 0xf6, 0xc3, 0xc4, 0x45, 0x42, 0x14, 0x06, + 0x0e, 0xc7, 0xef, 0x29, 0xac, 0xe9, 0x86, 0xf2, 0x99, 0xca, 0xab, 0xcb, 0xcb, 0xc8, 0xc1, 0xaa, + 0x72, 0x03, 0xdf, 0x5b, 0xa0, 0x6a, 0x33, 0x57, 0xc4, 0xa1, 0x7f, 0xd8, 0x61, 0x9c, 0x48, 0x62, + 0x01, 0x52, 0x9d, 0xc3, 0xbb, 0xcf, 0x6b, 0x37, 0xdb, 0xef, 0x03, 0x22, 0x9c, 0xeb, 0x82, 0x0a, + 0xb7, 0x84, 0x0c, 0x52, 0x37, 0xd4, 0x2c, 0x46, 0x33, 0x10, 0x0b, 0x2a, 0x45, 0x16, 0xde, 0x49, + 0xe4, 0xe2, 0x23, 0x81, 0x26, 0x7f, 0x31, 0x78, 0x8b, 0x9b, 0x71, 0xb1, 0x43, 0x48, 0x5d, 0xfd, + 0x08, 0x7f, 0x78, 0xf2, 0x04, 0x55, 0xd4, 0x1c, 0xec, 0xab, 0x96, 0x0e, 0x11, 0x02, 0x69, 0x0d, + 0x19, 0x81, 0x0f, 0x29, 0x75, 0x25, 0xa5, 0xe2, 0x89, 0x41, 0x4f, 0x5d, 0xc9, 0xee, 0xe5, 0xcb, + 0xfe, 0x3f, 0x2f, 0x9e, 0x06, 0x73 }; const char* shaderSource() { diff --git a/src/mbgl/programs/gl/shader_source.hpp b/src/mbgl/programs/gl/shader_source.hpp index f6de8a56cc..1a5fbddae3 100644 --- a/src/mbgl/programs/gl/shader_source.hpp +++ b/src/mbgl/programs/gl/shader_source.hpp @@ -8,6 +8,9 @@ namespace gl { const char* shaderSource(); +template <typename> +struct ShaderSource; + } // namespace gl } // namespace programs } // namespace mbgl diff --git a/src/mbgl/programs/gl/shaders.cpp b/src/mbgl/programs/gl/shaders.cpp index 3cc33992de..6fb4d70db9 100644 --- a/src/mbgl/programs/gl/shaders.cpp +++ b/src/mbgl/programs/gl/shaders.cpp @@ -1,4 +1,5 @@ #include <mbgl/programs/gl/shaders.hpp> +#include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/program_parameters.hpp> #include <mbgl/util/string.hpp> @@ -9,20 +10,17 @@ namespace mbgl { namespace programs { namespace gl { -std::string fragmentSource(const ProgramParameters& parameters, const char* fragmentSource) { - return parameters.getDefines() + fragmentShaderPrelude + fragmentSource; -} - -std::string vertexSource(const ProgramParameters& parameters, const char* vertexSource) { - return parameters.getDefines() + vertexShaderPrelude + vertexSource; -} - -std::string programIdentifier(const std::string& vertexSource, const std::string& fragmentSource) { +std::string programIdentifier(const std::string& defines1, + const std::string& defines2, + const uint8_t hash1[8], + const uint8_t hash2[8]) { std::string result; - result.reserve((sizeof(size_t) * 2) * 2 + 2); // 2 size_t hex values + "v2" - result += util::toHex(std::hash<std::string>()(vertexSource)); - result += util::toHex(std::hash<std::string>()(fragmentSource)); - result += "v3"; + result.reserve(8 + 8 + (sizeof(size_t) * 2) * 2 + 2); + result.append(util::toHex(std::hash<std::string>()(defines1))); + result.append(util::toHex(std::hash<std::string>()(defines2))); + result.append(hash1, hash2 + 8); + result.append(hash2, hash2 + 8); + result.append("v3"); return result; } diff --git a/src/mbgl/programs/gl/shaders.hpp b/src/mbgl/programs/gl/shaders.hpp index 5278ea54da..46a87f4af8 100644 --- a/src/mbgl/programs/gl/shaders.hpp +++ b/src/mbgl/programs/gl/shaders.hpp @@ -9,9 +9,10 @@ class ProgramParameters; namespace programs { namespace gl { -std::string fragmentSource(const ProgramParameters&, const char* fragmentSource); -std::string vertexSource(const ProgramParameters&, const char* vertexSource); -std::string programIdentifier(const std::string& vertexSource, const std::string& fragmentSource); +std::string programIdentifier(const std::string& defines1, + const std::string& defines2, + const uint8_t hash1[8], + const uint8_t hash2[8]); } // namespace gl } // namespace programs diff --git a/src/mbgl/programs/gl/symbol_icon.cpp b/src/mbgl/programs/gl/symbol_icon.cpp index 733d3b7ebd..6cb2b88543 100644 --- a/src/mbgl/programs/gl/symbol_icon.cpp +++ b/src/mbgl/programs/gl/symbol_icon.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/symbol_icon_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<SymbolIconProgram> { + static constexpr const char* name = "symbol_icon"; + static constexpr const uint8_t hash[8] = { 0x96, 0x0c, 0xef, 0xec, 0x37, 0x23, 0xf9, 0xb1 }; + static constexpr const auto vertexOffset = 50000; + static constexpr const auto fragmentOffset = 52654; +}; + +constexpr const char* ShaderSource<SymbolIconProgram>::name; +constexpr const uint8_t ShaderSource<SymbolIconProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<SymbolIconProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<SymbolIconProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "symbol_icon", - programs::gl::shaderSource() + 50000, programs::gl::shaderSource() + 52654); + return std::make_unique<gl::Program<SymbolIconProgram>>(programParameters); } } // namespace gfx @@ -39,7 +58,7 @@ uniform float u_fade_change; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -62,7 +81,7 @@ varying float v_fade_opacity; void main() { #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif diff --git a/src/mbgl/programs/gl/symbol_sdf_icon.cpp b/src/mbgl/programs/gl/symbol_sdf_icon.cpp index ef3ecd138c..d98554099f 100644 --- a/src/mbgl/programs/gl/symbol_sdf_icon.cpp +++ b/src/mbgl/programs/gl/symbol_sdf_icon.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/symbol_sdf_icon_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<SymbolSDFIconProgram> { + static constexpr const char* name = "symbol_sdf_icon"; + static constexpr const uint8_t hash[8] = { 0x13, 0xfc, 0x05, 0x2a, 0xd1, 0x93, 0xfb, 0x7d }; + static constexpr const auto vertexOffset = 53059; + static constexpr const auto fragmentOffset = 57099; +}; + +constexpr const char* ShaderSource<SymbolSDFIconProgram>::name; +constexpr const uint8_t ShaderSource<SymbolSDFIconProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<SymbolSDFIconProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<SymbolSDFIconProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "symbol_sdf_icon", - programs::gl::shaderSource() + 53059, programs::gl::shaderSource() + 57099); + return std::make_unique<gl::Program<SymbolSDFIconProgram>>(programParameters); } } // namespace gfx @@ -41,7 +60,7 @@ uniform highp float u_size; // used when size is both zoom and feature constant #ifndef HAS_UNIFORM_u_fill_color -uniform lowp float a_fill_color_t; +uniform lowp float u_fill_color_t; attribute highp vec4 a_fill_color; varying highp vec4 fill_color; #else @@ -50,7 +69,7 @@ uniform highp vec4 u_fill_color; #ifndef HAS_UNIFORM_u_halo_color -uniform lowp float a_halo_color_t; +uniform lowp float u_halo_color_t; attribute highp vec4 a_halo_color; varying highp vec4 halo_color; #else @@ -59,7 +78,7 @@ uniform highp vec4 u_halo_color; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -68,7 +87,7 @@ uniform lowp float u_opacity; #ifndef HAS_UNIFORM_u_halo_width -uniform lowp float a_halo_width_t; +uniform lowp float u_halo_width_t; attribute lowp vec2 a_halo_width; varying lowp float halo_width; #else @@ -77,7 +96,7 @@ uniform lowp float u_halo_width; #ifndef HAS_UNIFORM_u_halo_blur -uniform lowp float a_halo_blur_t; +uniform lowp float u_halo_blur_t; attribute lowp vec2 a_halo_blur; varying lowp float halo_blur; #else @@ -105,35 +124,35 @@ varying vec3 v_data1; void main() { #ifndef HAS_UNIFORM_u_fill_color - fill_color = unpack_mix_color(a_fill_color, a_fill_color_t); + fill_color = unpack_mix_color(a_fill_color, u_fill_color_t); #else highp vec4 fill_color = u_fill_color; #endif #ifndef HAS_UNIFORM_u_halo_color - halo_color = unpack_mix_color(a_halo_color, a_halo_color_t); + halo_color = unpack_mix_color(a_halo_color, u_halo_color_t); #else highp vec4 halo_color = u_halo_color; #endif #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif #ifndef HAS_UNIFORM_u_halo_width - halo_width = unpack_mix_vec2(a_halo_width, a_halo_width_t); + halo_width = unpack_mix_vec2(a_halo_width, u_halo_width_t); #else lowp float halo_width = u_halo_width; #endif #ifndef HAS_UNIFORM_u_halo_blur - halo_blur = unpack_mix_vec2(a_halo_blur, a_halo_blur_t); + halo_blur = unpack_mix_vec2(a_halo_blur, u_halo_blur_t); #else lowp float halo_blur = u_halo_blur; #endif diff --git a/src/mbgl/programs/gl/symbol_sdf_text.cpp b/src/mbgl/programs/gl/symbol_sdf_text.cpp index a0d810d1ce..81f3729d92 100644 --- a/src/mbgl/programs/gl/symbol_sdf_text.cpp +++ b/src/mbgl/programs/gl/symbol_sdf_text.cpp @@ -1,18 +1,37 @@ // NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. #include <mbgl/programs/symbol_sdf_text_program.hpp> +#include <mbgl/programs/gl/preludes.hpp> #include <mbgl/programs/gl/shader_source.hpp> #include <mbgl/gl/program.hpp> namespace mbgl { +namespace programs { +namespace gl { + +template <typename> +struct ShaderSource; + +template <> +struct ShaderSource<SymbolSDFTextProgram> { + static constexpr const char* name = "symbol_sdf_text"; + static constexpr const uint8_t hash[8] = { 0x13, 0xfc, 0x05, 0x2a, 0xd1, 0x93, 0xfb, 0x7d }; + static constexpr const auto vertexOffset = 53059; + static constexpr const auto fragmentOffset = 57099; +}; + +constexpr const char* ShaderSource<SymbolSDFTextProgram>::name; +constexpr const uint8_t ShaderSource<SymbolSDFTextProgram>::hash[8]; + +} // namespace gl +} // namespace programs + namespace gfx { template <> std::unique_ptr<Program<SymbolSDFTextProgram>> Context::createProgram<gl::Context>(const ProgramParameters& programParameters) { - return gl::Program<SymbolSDFTextProgram>::createProgram( - reinterpret_cast<gl::Context&>(*this), programParameters, "symbol_sdf_text", - programs::gl::shaderSource() + 53059, programs::gl::shaderSource() + 57099); + return std::make_unique<gl::Program<SymbolSDFTextProgram>>(programParameters); } } // namespace gfx @@ -41,7 +60,7 @@ uniform highp float u_size; // used when size is both zoom and feature constant #ifndef HAS_UNIFORM_u_fill_color -uniform lowp float a_fill_color_t; +uniform lowp float u_fill_color_t; attribute highp vec4 a_fill_color; varying highp vec4 fill_color; #else @@ -50,7 +69,7 @@ uniform highp vec4 u_fill_color; #ifndef HAS_UNIFORM_u_halo_color -uniform lowp float a_halo_color_t; +uniform lowp float u_halo_color_t; attribute highp vec4 a_halo_color; varying highp vec4 halo_color; #else @@ -59,7 +78,7 @@ uniform highp vec4 u_halo_color; #ifndef HAS_UNIFORM_u_opacity -uniform lowp float a_opacity_t; +uniform lowp float u_opacity_t; attribute lowp vec2 a_opacity; varying lowp float opacity; #else @@ -68,7 +87,7 @@ uniform lowp float u_opacity; #ifndef HAS_UNIFORM_u_halo_width -uniform lowp float a_halo_width_t; +uniform lowp float u_halo_width_t; attribute lowp vec2 a_halo_width; varying lowp float halo_width; #else @@ -77,7 +96,7 @@ uniform lowp float u_halo_width; #ifndef HAS_UNIFORM_u_halo_blur -uniform lowp float a_halo_blur_t; +uniform lowp float u_halo_blur_t; attribute lowp vec2 a_halo_blur; varying lowp float halo_blur; #else @@ -105,35 +124,35 @@ varying vec3 v_data1; void main() { #ifndef HAS_UNIFORM_u_fill_color - fill_color = unpack_mix_color(a_fill_color, a_fill_color_t); + fill_color = unpack_mix_color(a_fill_color, u_fill_color_t); #else highp vec4 fill_color = u_fill_color; #endif #ifndef HAS_UNIFORM_u_halo_color - halo_color = unpack_mix_color(a_halo_color, a_halo_color_t); + halo_color = unpack_mix_color(a_halo_color, u_halo_color_t); #else highp vec4 halo_color = u_halo_color; #endif #ifndef HAS_UNIFORM_u_opacity - opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, u_opacity_t); #else lowp float opacity = u_opacity; #endif #ifndef HAS_UNIFORM_u_halo_width - halo_width = unpack_mix_vec2(a_halo_width, a_halo_width_t); + halo_width = unpack_mix_vec2(a_halo_width, u_halo_width_t); #else lowp float halo_width = u_halo_width; #endif #ifndef HAS_UNIFORM_u_halo_blur - halo_blur = unpack_mix_vec2(a_halo_blur, a_halo_blur_t); + halo_blur = unpack_mix_vec2(a_halo_blur, u_halo_blur_t); #else lowp float halo_blur = u_halo_blur; #endif diff --git a/src/mbgl/programs/heatmap_program.hpp b/src/mbgl/programs/heatmap_program.hpp index 9563dd8d1b..537a9e9565 100644 --- a/src/mbgl/programs/heatmap_program.hpp +++ b/src/mbgl/programs/heatmap_program.hpp @@ -10,18 +10,18 @@ namespace mbgl { namespace uniforms { -MBGL_DEFINE_UNIFORM_SCALAR(float, u_intensity); +MBGL_DEFINE_UNIFORM_SCALAR(float, intensity); } // namespace uniforms class HeatmapProgram : public Program< HeatmapProgram, gfx::PrimitiveType::Triangle, TypeList< - attributes::a_pos>, + attributes::pos>, TypeList< - uniforms::u_intensity, - uniforms::u_matrix, - uniforms::heatmap::u_extrude_scale>, + uniforms::intensity, + uniforms::matrix, + uniforms::heatmap::extrude_scale>, TypeList<>, style::HeatmapPaintProperties> { @@ -52,7 +52,7 @@ public: HeatmapLayerPrograms(gfx::Context& context, const ProgramParameters& programParameters) : heatmap(context, programParameters), heatmapTexture(context, programParameters) {} - ProgramMap<HeatmapProgram> heatmap; + HeatmapProgram heatmap; HeatmapTextureProgram heatmapTexture; }; diff --git a/src/mbgl/programs/heatmap_texture_program.hpp b/src/mbgl/programs/heatmap_texture_program.hpp index 954e03f9b6..6762f8c7f4 100644 --- a/src/mbgl/programs/heatmap_texture_program.hpp +++ b/src/mbgl/programs/heatmap_texture_program.hpp @@ -12,14 +12,14 @@ namespace mbgl { class HeatmapTextureProgram : public Program< HeatmapTextureProgram, gfx::PrimitiveType::Triangle, - TypeList<attributes::a_pos>, + TypeList<attributes::pos>, TypeList< - uniforms::u_matrix, - uniforms::u_world, - uniforms::u_opacity>, + uniforms::matrix, + uniforms::world, + uniforms::opacity>, TypeList< - textures::u_image, - textures::u_color_ramp>, + textures::image, + textures::color_ramp>, style::Properties<>> { public: using Program::Program; diff --git a/src/mbgl/programs/hillshade_prepare_program.hpp b/src/mbgl/programs/hillshade_prepare_program.hpp index 0243cc1879..2d76145bc3 100644 --- a/src/mbgl/programs/hillshade_prepare_program.hpp +++ b/src/mbgl/programs/hillshade_prepare_program.hpp @@ -9,23 +9,23 @@ namespace mbgl { namespace uniforms { -MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, u_dimension); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_maxzoom); +MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, dimension); +MBGL_DEFINE_UNIFORM_SCALAR(float, maxzoom); } // namespace uniforms class HillshadePrepareProgram : public Program< HillshadePrepareProgram, gfx::PrimitiveType::Triangle, TypeList< - attributes::a_pos, - attributes::a_texture_pos>, + attributes::pos, + attributes::texture_pos>, TypeList< - uniforms::u_matrix, - uniforms::u_dimension, - uniforms::u_zoom, - uniforms::u_maxzoom>, + uniforms::matrix, + uniforms::dimension, + uniforms::zoom, + uniforms::maxzoom>, TypeList< - textures::u_image>, + textures::image>, style::Properties<>> { public: using Program::Program; diff --git a/src/mbgl/programs/hillshade_program.hpp b/src/mbgl/programs/hillshade_program.hpp index 68d67917df..33f91abef0 100644 --- a/src/mbgl/programs/hillshade_program.hpp +++ b/src/mbgl/programs/hillshade_program.hpp @@ -11,28 +11,28 @@ namespace mbgl { namespace uniforms { -MBGL_DEFINE_UNIFORM_SCALAR(Color, u_shadow); -MBGL_DEFINE_UNIFORM_SCALAR(Color, u_highlight); -MBGL_DEFINE_UNIFORM_SCALAR(Color, u_accent); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_light); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_latrange); +MBGL_DEFINE_UNIFORM_SCALAR(Color, shadow); +MBGL_DEFINE_UNIFORM_SCALAR(Color, highlight); +MBGL_DEFINE_UNIFORM_SCALAR(Color, accent); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, light); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, latrange); } // namespace uniforms class HillshadeProgram : public Program< HillshadeProgram, gfx::PrimitiveType::Triangle, TypeList< - attributes::a_pos, - attributes::a_texture_pos>, + attributes::pos, + attributes::texture_pos>, TypeList< - uniforms::u_matrix, - uniforms::u_highlight, - uniforms::u_shadow, - uniforms::u_accent, - uniforms::u_light, - uniforms::u_latrange>, + uniforms::matrix, + uniforms::highlight, + uniforms::shadow, + uniforms::accent, + uniforms::light, + uniforms::latrange>, TypeList< - textures::u_image>, + textures::image>, style::HillshadePaintProperties>{ public: using Program::Program; diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp index 74a1ba3162..9428b5d9d6 100644 --- a/src/mbgl/programs/line_program.cpp +++ b/src/mbgl/programs/line_program.cpp @@ -19,26 +19,26 @@ using namespace style; static_assert(sizeof(LineLayoutVertex) == 12, "expected LineLayoutVertex size"); template <class Values, class...Args> -Values makeValues(const RenderLinePaintProperties::PossiblyEvaluated& properties, +Values makeValues(const style::LinePaintProperties::PossiblyEvaluated& properties, const RenderTile& tile, const TransformState& state, const std::array<float, 2>& pixelsToGLUnits, Args&&... args) { return Values { - uniforms::u_matrix::Value( + uniforms::matrix::Value( tile.translatedMatrix(properties.get<LineTranslate>(), properties.get<LineTranslateAnchor>(), state) ), - uniforms::u_ratio::Value( 1.0f / tile.id.pixelsToTileUnits(1.0, state.getZoom()) ), - uniforms::u_gl_units_to_pixels::Value({ {1.0f / pixelsToGLUnits[0], 1.0f / pixelsToGLUnits[1]} }), + uniforms::ratio::Value( 1.0f / tile.id.pixelsToTileUnits(1.0, state.getZoom()) ), + uniforms::gl_units_to_pixels::Value({ {1.0f / pixelsToGLUnits[0], 1.0f / pixelsToGLUnits[1]} }), std::forward<Args>(args)... }; } LineProgram::LayoutUniformValues -LineProgram::layoutUniformValues(const RenderLinePaintProperties::PossiblyEvaluated& properties, +LineProgram::layoutUniformValues(const style::LinePaintProperties::PossiblyEvaluated& properties, const RenderTile& tile, const TransformState& state, const std::array<float, 2>& pixelsToGLUnits) { @@ -51,7 +51,7 @@ LineProgram::layoutUniformValues(const RenderLinePaintProperties::PossiblyEvalua } LineSDFProgram::LayoutUniformValues -LineSDFProgram::layoutUniformValues(const RenderLinePaintProperties::PossiblyEvaluated& properties, +LineSDFProgram::layoutUniformValues(const style::LinePaintProperties::PossiblyEvaluated& properties, float pixelRatio, const RenderTile& tile, const TransformState& state, @@ -78,17 +78,17 @@ LineSDFProgram::layoutUniformValues(const RenderLinePaintProperties::PossiblyEva tile, state, pixelsToGLUnits, - uniforms::u_patternscale_a::Value( scaleA ), - uniforms::u_patternscale_b::Value( scaleB ), - uniforms::u_tex_y_a::Value( posA.y ), - uniforms::u_tex_y_b::Value( posB.y ), - uniforms::u_mix::Value( crossfade.t ), - uniforms::u_sdfgamma::Value( atlasWidth / (std::min(widthA, widthB) * 256.0f * pixelRatio) / 2.0f ) + uniforms::patternscale_a::Value( scaleA ), + uniforms::patternscale_b::Value( scaleB ), + uniforms::tex_y_a::Value( posA.y ), + uniforms::tex_y_b::Value( posB.y ), + uniforms::mix::Value( crossfade.t ), + uniforms::sdfgamma::Value( atlasWidth / (std::min(widthA, widthB) * 256.0f * pixelRatio) / 2.0f ) ); } LinePatternProgram::LayoutUniformValues LinePatternProgram::layoutUniformValues( - const RenderLinePaintProperties::PossiblyEvaluated& properties, + const style::LinePaintProperties::PossiblyEvaluated& properties, const RenderTile& tile, const TransformState& state, const std::array<float, 2>& pixelsToGLUnits, @@ -103,14 +103,14 @@ LinePatternProgram::LayoutUniformValues LinePatternProgram::layoutUniformValues( tile, state, pixelsToGLUnits, - uniforms::u_scale::Value ({ {pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale} }), - uniforms::u_texsize::Value( atlasSize ), - uniforms::u_fade::Value( crossfade.t ) + uniforms::scale::Value ({ {pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale} }), + uniforms::texsize::Value( atlasSize ), + uniforms::fade::Value( crossfade.t ) ); } LineGradientProgram::LayoutUniformValues LineGradientProgram::layoutUniformValues( - const RenderLinePaintProperties::PossiblyEvaluated& properties, + const style::LinePaintProperties::PossiblyEvaluated& properties, const RenderTile& tile, const TransformState& state, const std::array<float, 2>& pixelsToGLUnits) { diff --git a/src/mbgl/programs/line_program.hpp b/src/mbgl/programs/line_program.hpp index 05546e3cbe..ed149abb33 100644 --- a/src/mbgl/programs/line_program.hpp +++ b/src/mbgl/programs/line_program.hpp @@ -17,29 +17,29 @@ class LinePatternPos; class ImagePosition; namespace uniforms { -MBGL_DEFINE_UNIFORM_SCALAR(float, u_ratio); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_tex_y_a); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_tex_y_b); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_sdfgamma); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_patternscale_a); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_patternscale_b); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_gl_units_to_pixels); +MBGL_DEFINE_UNIFORM_SCALAR(float, ratio); +MBGL_DEFINE_UNIFORM_SCALAR(float, tex_y_a); +MBGL_DEFINE_UNIFORM_SCALAR(float, tex_y_b); +MBGL_DEFINE_UNIFORM_SCALAR(float, sdfgamma); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, patternscale_a); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, patternscale_b); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, gl_units_to_pixels); } // namespace uniforms using LineLayoutAttributes = TypeList< - attributes::a_pos_normal, - attributes::a_data<uint8_t, 4>>; + attributes::pos_normal, + attributes::data<uint8_t, 4>>; class LineProgram : public Program< LineProgram, gfx::PrimitiveType::Triangle, LineLayoutAttributes, TypeList< - uniforms::u_matrix, - uniforms::u_ratio, - uniforms::u_gl_units_to_pixels>, + uniforms::matrix, + uniforms::ratio, + uniforms::gl_units_to_pixels>, TypeList<>, - RenderLinePaintProperties> + style::LinePaintProperties> { public: using Program::Program; @@ -90,7 +90,7 @@ public: static const int8_t extrudeScale = 63; static LayoutUniformValues - layoutUniformValues(const RenderLinePaintProperties::PossiblyEvaluated&, + layoutUniformValues(const style::LinePaintProperties::PossiblyEvaluated&, const RenderTile&, const TransformState&, const std::array<float, 2>& pixelsToGLUnits); @@ -101,21 +101,21 @@ class LinePatternProgram : public Program< gfx::PrimitiveType::Triangle, LineLayoutAttributes, TypeList< - uniforms::u_matrix, - uniforms::u_ratio, - uniforms::u_gl_units_to_pixels, - uniforms::u_scale, - uniforms::u_texsize, - uniforms::u_fade>, + uniforms::matrix, + uniforms::ratio, + uniforms::gl_units_to_pixels, + uniforms::scale, + uniforms::texsize, + uniforms::fade>, TypeList< - textures::u_image>, - RenderLinePaintProperties> + textures::image>, + style::LinePaintProperties> { public: using Program::Program; static LayoutUniformValues - layoutUniformValues(const RenderLinePaintProperties::PossiblyEvaluated&, + layoutUniformValues(const style::LinePaintProperties::PossiblyEvaluated&, const RenderTile&, const TransformState&, const std::array<float, 2>& pixelsToGLUnits, @@ -129,24 +129,24 @@ class LineSDFProgram : public Program< gfx::PrimitiveType::Triangle, LineLayoutAttributes, TypeList< - uniforms::u_matrix, - uniforms::u_ratio, - uniforms::u_gl_units_to_pixels, - uniforms::u_patternscale_a, - uniforms::u_patternscale_b, - uniforms::u_tex_y_a, - uniforms::u_tex_y_b, - uniforms::u_mix, - uniforms::u_sdfgamma>, + uniforms::matrix, + uniforms::ratio, + uniforms::gl_units_to_pixels, + uniforms::patternscale_a, + uniforms::patternscale_b, + uniforms::tex_y_a, + uniforms::tex_y_b, + uniforms::mix, + uniforms::sdfgamma>, TypeList< - textures::u_image>, - RenderLinePaintProperties> + textures::image>, + style::LinePaintProperties> { public: using Program::Program; static LayoutUniformValues - layoutUniformValues(const RenderLinePaintProperties::PossiblyEvaluated&, + layoutUniformValues(const style::LinePaintProperties::PossiblyEvaluated&, float pixelRatio, const RenderTile&, const TransformState&, @@ -162,18 +162,18 @@ class LineGradientProgram : public Program< gfx::PrimitiveType::Triangle, LineLayoutAttributes, TypeList< - uniforms::u_matrix, - uniforms::u_ratio, - uniforms::u_gl_units_to_pixels>, + uniforms::matrix, + uniforms::ratio, + uniforms::gl_units_to_pixels>, TypeList< - textures::u_image>, - RenderLinePaintProperties> + textures::image>, + style::LinePaintProperties> { public: using Program::Program; static LayoutUniformValues - layoutUniformValues(const RenderLinePaintProperties::PossiblyEvaluated&, + layoutUniformValues(const style::LinePaintProperties::PossiblyEvaluated&, const RenderTile&, const TransformState&, const std::array<float, 2>& pixelsToGLUnits); @@ -189,10 +189,10 @@ public: lineGradient(context, programParameters), lineSDF(context, programParameters), linePattern(context, programParameters) {} - ProgramMap<LineProgram> line; - ProgramMap<LineGradientProgram> lineGradient; - ProgramMap<LineSDFProgram> lineSDF; - ProgramMap<LinePatternProgram> linePattern; + LineProgram line; + LineGradientProgram lineGradient; + LineSDFProgram lineSDF; + LinePatternProgram linePattern; }; } // namespace mbgl diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index 240da22b4f..e4d2af95f8 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -109,36 +109,6 @@ public: } }; -template <class Program> -class ProgramMap { -public: - using PaintProperties = typename Program::PaintProperties; - using Binders = typename Program::Binders; - using Bitset = typename Binders::Bitset; - - ProgramMap(gfx::Context& context_, ProgramParameters parameters_) - : context(context_), - parameters(std::move(parameters_)) { - } - - Program& get(const typename PaintProperties::PossiblyEvaluated& currentProperties) { - Bitset bits = Binders::constants(currentProperties); - auto it = programs.find(bits); - if (it != programs.end()) { - return it->second; - } - return programs.emplace(std::piecewise_construct, - std::forward_as_tuple(bits), - std::forward_as_tuple(context, - parameters.withAdditionalDefines(Binders::defines(currentProperties)))).first->second; - } - -private: - gfx::Context& context; - ProgramParameters parameters; - std::unordered_map<Bitset, Program> programs; -}; - class LayerTypePrograms { public: virtual ~LayerTypePrograms() = default; diff --git a/src/mbgl/programs/program_parameters.cpp b/src/mbgl/programs/program_parameters.cpp index 6b6c2bb2fe..e692b74e0e 100644 --- a/src/mbgl/programs/program_parameters.cpp +++ b/src/mbgl/programs/program_parameters.cpp @@ -40,13 +40,4 @@ optional<std::string> ProgramParameters::cachePath(const char* name) const { } } -ProgramParameters ProgramParameters::withAdditionalDefines(const std::vector<std::string>& additionalDefines) const { - ProgramParameters result(*this); - for (const auto& define : additionalDefines) { - result.defines += define; - result.defines += "\n"; - } - return result; -} - } // namespace mbgl diff --git a/src/mbgl/programs/program_parameters.hpp b/src/mbgl/programs/program_parameters.hpp index e94e61c217..71ad454399 100644 --- a/src/mbgl/programs/program_parameters.hpp +++ b/src/mbgl/programs/program_parameters.hpp @@ -3,7 +3,6 @@ #include <mbgl/util/optional.hpp> #include <string> -#include <vector> namespace mbgl { @@ -14,8 +13,6 @@ public: const std::string& getDefines() const; optional<std::string> cachePath(const char* name) const; - ProgramParameters withAdditionalDefines(const std::vector<std::string>& defines) const; - private: std::string defines; optional<std::string> cacheDir; diff --git a/src/mbgl/programs/raster_program.hpp b/src/mbgl/programs/raster_program.hpp index 55f1fb0a2e..e84ada0bdc 100644 --- a/src/mbgl/programs/raster_program.hpp +++ b/src/mbgl/programs/raster_program.hpp @@ -10,38 +10,38 @@ namespace mbgl { namespace uniforms { -MBGL_DEFINE_UNIFORM_SCALAR(float, u_fade_t); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_buffer_scale); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_brightness_low); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_brightness_high); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_saturation_factor); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_contrast_factor); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale_parent); -MBGL_DEFINE_UNIFORM_VECTOR(float, 3, u_spin_weights); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_tl_parent); +MBGL_DEFINE_UNIFORM_SCALAR(float, fade_t); +MBGL_DEFINE_UNIFORM_SCALAR(float, buffer_scale); +MBGL_DEFINE_UNIFORM_SCALAR(float, brightness_low); +MBGL_DEFINE_UNIFORM_SCALAR(float, brightness_high); +MBGL_DEFINE_UNIFORM_SCALAR(float, saturation_factor); +MBGL_DEFINE_UNIFORM_SCALAR(float, contrast_factor); +MBGL_DEFINE_UNIFORM_SCALAR(float, scale_parent); +MBGL_DEFINE_UNIFORM_VECTOR(float, 3, spin_weights); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, tl_parent); } // namespace uniforms class RasterProgram : public Program< RasterProgram, gfx::PrimitiveType::Triangle, TypeList< - attributes::a_pos, - attributes::a_texture_pos>, + attributes::pos, + attributes::texture_pos>, TypeList< - uniforms::u_matrix, - uniforms::u_opacity, - uniforms::u_fade_t, - uniforms::u_brightness_low, - uniforms::u_brightness_high, - uniforms::u_saturation_factor, - uniforms::u_contrast_factor, - uniforms::u_spin_weights, - uniforms::u_buffer_scale, - uniforms::u_scale_parent, - uniforms::u_tl_parent>, + uniforms::matrix, + uniforms::opacity, + uniforms::fade_t, + uniforms::brightness_low, + uniforms::brightness_high, + uniforms::saturation_factor, + uniforms::contrast_factor, + uniforms::spin_weights, + uniforms::buffer_scale, + uniforms::scale_parent, + uniforms::tl_parent>, TypeList< - textures::u_image0, - textures::u_image1>, + textures::image0, + textures::image1>, style::RasterPaintProperties> { public: diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp index 2300dedff3..d6a7a10368 100644 --- a/src/mbgl/programs/symbol_program.cpp +++ b/src/mbgl/programs/symbol_program.cpp @@ -42,6 +42,7 @@ std::unique_ptr<SymbolSizeBinder> SymbolSizeBinder::create(const float tileZoom, template <class Values, class...Args> Values makeValues(const bool isText, + const bool hasVariablePacement, const style::SymbolPropertyValues& values, const Size& texsize, const std::array<float, 2>& pixelsToGLUnits, @@ -71,7 +72,7 @@ Values makeValues(const bool isText, const bool rotateInShader = rotateWithMap && !pitchWithMap && !alongLine; mat4 labelPlaneMatrix; - if (alongLine) { + if (alongLine || (isText && hasVariablePacement)) { // For labels that follow lines the first part of the projection is handled on the cpu. // Pass an identity matrix because no transformation needs to be done in the vertex shader. matrix::identity(labelPlaneMatrix); @@ -82,30 +83,31 @@ Values makeValues(const bool isText, mat4 glCoordMatrix = getGlCoordMatrix(tile.matrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits); return Values { - uniforms::u_matrix::Value( tile.translatedMatrix(values.translate, + uniforms::matrix::Value( tile.translatedMatrix(values.translate, values.translateAnchor, state) ), - uniforms::u_label_plane_matrix::Value(labelPlaneMatrix), - uniforms::u_gl_coord_matrix::Value( tile.translateVtxMatrix(glCoordMatrix, + uniforms::label_plane_matrix::Value(labelPlaneMatrix), + uniforms::gl_coord_matrix::Value( tile.translateVtxMatrix(glCoordMatrix, values.translate, values.translateAnchor, state, true) ), - uniforms::u_extrude_scale::Value( extrudeScale ), - uniforms::u_texsize::Value( texsize ), - uniforms::u_fade_change::Value( symbolFadeChange ), - uniforms::u_is_text::Value( isText ), - uniforms::u_camera_to_center_distance::Value( state.getCameraToCenterDistance() ), - uniforms::u_pitch::Value( state.getPitch() ), - uniforms::u_pitch_with_map::Value( pitchWithMap ), - uniforms::u_rotate_symbol::Value( rotateInShader ), - uniforms::u_aspect_ratio::Value( state.getSize().aspectRatio() ), + uniforms::extrude_scale::Value( extrudeScale ), + uniforms::texsize::Value( texsize ), + uniforms::fade_change::Value( symbolFadeChange ), + uniforms::is_text::Value( isText ), + uniforms::camera_to_center_distance::Value( state.getCameraToCenterDistance() ), + uniforms::pitch::Value( state.getPitch() ), + uniforms::pitch_with_map::Value( pitchWithMap ), + uniforms::rotate_symbol::Value( rotateInShader ), + uniforms::aspect_ratio::Value( state.getSize().aspectRatio() ), std::forward<Args>(args)... }; } SymbolIconProgram::LayoutUniformValues SymbolIconProgram::layoutUniformValues(const bool isText, + const bool hasVariablePacement, const style::SymbolPropertyValues& values, const Size& texsize, const std::array<float, 2>& pixelsToGLUnits, @@ -115,6 +117,7 @@ SymbolIconProgram::layoutUniformValues(const bool isText, const float symbolFadeChange) { return makeValues<SymbolIconProgram::LayoutUniformValues>( isText, + hasVariablePacement, values, texsize, pixelsToGLUnits, @@ -128,6 +131,7 @@ SymbolIconProgram::layoutUniformValues(const bool isText, template <class Name, class PaintProperties> typename SymbolSDFProgram<Name, PaintProperties>::LayoutUniformValues SymbolSDFProgram<Name, PaintProperties>::layoutUniformValues(const bool isText, + const bool hasVariablePacement, const style::SymbolPropertyValues& values, const Size& texsize, const std::array<float, 2>& pixelsToGLUnits, @@ -142,6 +146,7 @@ SymbolSDFProgram<Name, PaintProperties>::layoutUniformValues(const bool isText, return makeValues<SymbolSDFProgram<Name, PaintProperties>::LayoutUniformValues>( isText, + hasVariablePacement, values, texsize, pixelsToGLUnits, @@ -149,8 +154,8 @@ SymbolSDFProgram<Name, PaintProperties>::layoutUniformValues(const bool isText, tile, state, symbolFadeChange, - uniforms::u_gamma_scale::Value( gammaScale ), - uniforms::u_is_halo::Value( part == SymbolSDFPart::Halo ) + uniforms::gamma_scale::Value( gammaScale ), + uniforms::is_halo::Value( part == SymbolSDFPart::Halo ) ); } diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 383f5162d8..d640eb74da 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -1,6 +1,5 @@ #pragma once -#include <mbgl/gl/program.hpp> #include <mbgl/math/clamp.hpp> #include <mbgl/util/interpolate.hpp> @@ -29,27 +28,27 @@ class RenderTile; class TransformState; namespace uniforms { -MBGL_DEFINE_UNIFORM_MATRIX(double, 4, u_gl_coord_matrix); -MBGL_DEFINE_UNIFORM_MATRIX(double, 4, u_label_plane_matrix); -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_halo); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_gamma_scale); - -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_text); -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_zoom_constant); -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_feature_constant); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_size_t); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_size); -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_symbol); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio); +MBGL_DEFINE_UNIFORM_MATRIX(double, 4, gl_coord_matrix); +MBGL_DEFINE_UNIFORM_MATRIX(double, 4, label_plane_matrix); +MBGL_DEFINE_UNIFORM_SCALAR(bool, is_halo); +MBGL_DEFINE_UNIFORM_SCALAR(float, gamma_scale); + +MBGL_DEFINE_UNIFORM_SCALAR(bool, is_text); +MBGL_DEFINE_UNIFORM_SCALAR(bool, is_size_zoom_constant); +MBGL_DEFINE_UNIFORM_SCALAR(bool, is_size_feature_constant); +MBGL_DEFINE_UNIFORM_SCALAR(float, size_t); +MBGL_DEFINE_UNIFORM_SCALAR(float, size); +MBGL_DEFINE_UNIFORM_SCALAR(bool, rotate_symbol); +MBGL_DEFINE_UNIFORM_SCALAR(float, aspect_ratio); } // namespace uniforms using SymbolLayoutAttributes = TypeList< - attributes::a_pos_offset, - attributes::a_data<uint16_t, 4>>; + attributes::pos_offset, + attributes::data<uint16_t, 4>>; -using SymbolDynamicLayoutAttributes = TypeList<attributes::a_projected_pos>; +using SymbolDynamicLayoutAttributes = TypeList<attributes::projected_pos>; -using SymbolOpacityAttributes = TypeList<attributes::a_fade_opacity>; +using SymbolOpacityAttributes = TypeList<attributes::fade_opacity>; struct ZoomEvaluatedSize { bool isZoomConstant; @@ -67,10 +66,10 @@ public: virtual ~SymbolSizeBinder() = default; using UniformList = TypeList< - uniforms::u_is_size_zoom_constant, - uniforms::u_is_size_feature_constant, - uniforms::u_size_t, - uniforms::u_size>; + uniforms::is_size_zoom_constant, + uniforms::is_size_feature_constant, + uniforms::size_t, + uniforms::size>; using UniformValues = gfx::UniformValues<UniformList>; static std::unique_ptr<SymbolSizeBinder> create(const float tileZoom, @@ -83,10 +82,10 @@ public: UniformValues uniformValues(float currentZoom) const { const ZoomEvaluatedSize u = evaluateForZoom(currentZoom); return UniformValues { - uniforms::u_is_size_zoom_constant::Value( u.isZoomConstant ), - uniforms::u_is_size_feature_constant::Value( u.isFeatureConstant), - uniforms::u_size_t::Value( u.sizeT ), - uniforms::u_size::Value( u.size ) + uniforms::is_size_zoom_constant::Value( u.isZoomConstant ), + uniforms::is_size_feature_constant::Value( u.isFeatureConstant), + uniforms::size_t::Value( u.sizeT ), + uniforms::size::Value( u.size ) }; } }; @@ -348,26 +347,27 @@ class SymbolIconProgram : public SymbolProgram< gfx::PrimitiveType::Triangle, SymbolLayoutAttributes, TypeList< - uniforms::u_matrix, - uniforms::u_label_plane_matrix, - uniforms::u_gl_coord_matrix, - uniforms::u_extrude_scale, - uniforms::u_texsize, - uniforms::u_fade_change, - uniforms::u_is_text, - uniforms::u_camera_to_center_distance, - uniforms::u_pitch, - uniforms::u_pitch_with_map, - uniforms::u_rotate_symbol, - uniforms::u_aspect_ratio>, + uniforms::matrix, + uniforms::label_plane_matrix, + uniforms::gl_coord_matrix, + uniforms::extrude_scale, + uniforms::texsize, + uniforms::fade_change, + uniforms::is_text, + uniforms::camera_to_center_distance, + uniforms::pitch, + uniforms::pitch_with_map, + uniforms::rotate_symbol, + uniforms::aspect_ratio>, TypeList< - textures::u_texture>, + textures::texture>, style::IconPaintProperties> { public: using SymbolProgram::SymbolProgram; static LayoutUniformValues layoutUniformValues(const bool isText, + const bool hasVariablePacement, const style::SymbolPropertyValues&, const Size& texsize, const std::array<float, 2>& pixelsToGLUnits, @@ -388,22 +388,22 @@ class SymbolSDFProgram : public SymbolProgram< gfx::PrimitiveType::Triangle, SymbolLayoutAttributes, TypeList< - uniforms::u_matrix, - uniforms::u_label_plane_matrix, - uniforms::u_gl_coord_matrix, - uniforms::u_extrude_scale, - uniforms::u_texsize, - uniforms::u_fade_change, - uniforms::u_is_text, - uniforms::u_camera_to_center_distance, - uniforms::u_pitch, - uniforms::u_pitch_with_map, - uniforms::u_rotate_symbol, - uniforms::u_aspect_ratio, - uniforms::u_gamma_scale, - uniforms::u_is_halo>, + uniforms::matrix, + uniforms::label_plane_matrix, + uniforms::gl_coord_matrix, + uniforms::extrude_scale, + uniforms::texsize, + uniforms::fade_change, + uniforms::is_text, + uniforms::camera_to_center_distance, + uniforms::pitch, + uniforms::pitch_with_map, + uniforms::rotate_symbol, + uniforms::aspect_ratio, + uniforms::gamma_scale, + uniforms::is_halo>, TypeList< - textures::u_texture>, + textures::texture>, PaintProperties> { public: @@ -412,22 +412,22 @@ public: gfx::PrimitiveType::Triangle, SymbolLayoutAttributes, TypeList< - uniforms::u_matrix, - uniforms::u_label_plane_matrix, - uniforms::u_gl_coord_matrix, - uniforms::u_extrude_scale, - uniforms::u_texsize, - uniforms::u_fade_change, - uniforms::u_is_text, - uniforms::u_camera_to_center_distance, - uniforms::u_pitch, - uniforms::u_pitch_with_map, - uniforms::u_rotate_symbol, - uniforms::u_aspect_ratio, - uniforms::u_gamma_scale, - uniforms::u_is_halo>, + uniforms::matrix, + uniforms::label_plane_matrix, + uniforms::gl_coord_matrix, + uniforms::extrude_scale, + uniforms::texsize, + uniforms::fade_change, + uniforms::is_text, + uniforms::camera_to_center_distance, + uniforms::pitch, + uniforms::pitch_with_map, + uniforms::rotate_symbol, + uniforms::aspect_ratio, + uniforms::gamma_scale, + uniforms::is_halo>, TypeList< - textures::u_texture>, + textures::texture>, PaintProperties>; using LayoutUniformValues = typename BaseProgram::LayoutUniformValues; @@ -437,6 +437,7 @@ public: using BaseProgram::BaseProgram; static LayoutUniformValues layoutUniformValues(const bool isText, + const bool hasVariablePacement, const style::SymbolPropertyValues&, const Size& texsize, const std::array<float, 2>& pixelsToGLUnits, @@ -469,9 +470,9 @@ public: symbolGlyph(context, programParameters), collisionBox(context, programParameters), collisionCircle(context, programParameters) {} - ProgramMap<SymbolIconProgram> symbolIcon; - ProgramMap<SymbolSDFIconProgram> symbolIconSDF; - ProgramMap<SymbolSDFTextProgram> symbolGlyph; + SymbolIconProgram symbolIcon; + SymbolSDFIconProgram symbolIconSDF; + SymbolSDFTextProgram symbolGlyph; CollisionBoxProgram collisionBox; CollisionCircleProgram collisionCircle; }; diff --git a/src/mbgl/programs/textures.hpp b/src/mbgl/programs/textures.hpp index 32bc4a4a35..4c9de53366 100644 --- a/src/mbgl/programs/textures.hpp +++ b/src/mbgl/programs/textures.hpp @@ -5,11 +5,11 @@ namespace mbgl { namespace textures { -MBGL_DEFINE_TEXTURE(u_image); -MBGL_DEFINE_TEXTURE(u_image0); -MBGL_DEFINE_TEXTURE(u_image1); -MBGL_DEFINE_TEXTURE(u_color_ramp); -MBGL_DEFINE_TEXTURE(u_texture); +MBGL_DEFINE_TEXTURE(image); +MBGL_DEFINE_TEXTURE(image0); +MBGL_DEFINE_TEXTURE(image1); +MBGL_DEFINE_TEXTURE(color_ramp); +MBGL_DEFINE_TEXTURE(texture); } // namespace textures } // namespace mbgl diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp index 79febf7f73..702b21def9 100644 --- a/src/mbgl/programs/uniforms.hpp +++ b/src/mbgl/programs/uniforms.hpp @@ -9,61 +9,61 @@ namespace uniforms { // Uniforms common to several shaders. -MBGL_DEFINE_UNIFORM_MATRIX(double, 4, u_matrix); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_opacity); -MBGL_DEFINE_UNIFORM_SCALAR(Color, u_color); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_blur); +MBGL_DEFINE_UNIFORM_MATRIX(double, 4, matrix); +MBGL_DEFINE_UNIFORM_SCALAR(float, opacity); +MBGL_DEFINE_UNIFORM_SCALAR(Color, color); +MBGL_DEFINE_UNIFORM_SCALAR(float, blur); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_zoom); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_collision_y_stretch); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_pitch); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_bearing); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_radius); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_stroke_width); -MBGL_DEFINE_UNIFORM_SCALAR(Color, u_stroke_color); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_stroke_opacity); -MBGL_DEFINE_UNIFORM_SCALAR(Color, u_fill_color); -MBGL_DEFINE_UNIFORM_SCALAR(Color, u_halo_color); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_halo_width); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_halo_blur); -MBGL_DEFINE_UNIFORM_SCALAR(Color, u_outline_color); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_height); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_base); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_width); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_floorwidth); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_gapwidth); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_offset); -MBGL_DEFINE_UNIFORM_SCALAR(Size, u_world); -MBGL_DEFINE_UNIFORM_SCALAR(Size, u_texsize); -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_pitch_with_map); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_camera_to_center_distance); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_fade); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_fade_change); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_weight); +MBGL_DEFINE_UNIFORM_SCALAR(float, zoom); +MBGL_DEFINE_UNIFORM_SCALAR(float, collision_y_stretch); +MBGL_DEFINE_UNIFORM_SCALAR(float, pitch); +MBGL_DEFINE_UNIFORM_SCALAR(float, bearing); +MBGL_DEFINE_UNIFORM_SCALAR(float, radius); +MBGL_DEFINE_UNIFORM_SCALAR(float, stroke_width); +MBGL_DEFINE_UNIFORM_SCALAR(Color, stroke_color); +MBGL_DEFINE_UNIFORM_SCALAR(float, stroke_opacity); +MBGL_DEFINE_UNIFORM_SCALAR(Color, fill_color); +MBGL_DEFINE_UNIFORM_SCALAR(Color, halo_color); +MBGL_DEFINE_UNIFORM_SCALAR(float, halo_width); +MBGL_DEFINE_UNIFORM_SCALAR(float, halo_blur); +MBGL_DEFINE_UNIFORM_SCALAR(Color, outline_color); +MBGL_DEFINE_UNIFORM_SCALAR(float, height); +MBGL_DEFINE_UNIFORM_SCALAR(float, base); +MBGL_DEFINE_UNIFORM_SCALAR(float, width); +MBGL_DEFINE_UNIFORM_SCALAR(float, floorwidth); +MBGL_DEFINE_UNIFORM_SCALAR(float, gapwidth); +MBGL_DEFINE_UNIFORM_SCALAR(float, offset); +MBGL_DEFINE_UNIFORM_SCALAR(Size, world); +MBGL_DEFINE_UNIFORM_SCALAR(Size, texsize); +MBGL_DEFINE_UNIFORM_SCALAR(bool, pitch_with_map); +MBGL_DEFINE_UNIFORM_SCALAR(float, camera_to_center_distance); +MBGL_DEFINE_UNIFORM_SCALAR(float, fade); +MBGL_DEFINE_UNIFORM_SCALAR(float, fade_change); +MBGL_DEFINE_UNIFORM_SCALAR(float, weight); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_extrude_scale); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, extrude_scale); namespace heatmap { -MBGL_DEFINE_UNIFORM_SCALAR(float, u_extrude_scale); +MBGL_DEFINE_UNIFORM_SCALAR(float, extrude_scale); } // namespace heatmap -MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 4, u_pattern_from); -MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 4, u_pattern_to); -MBGL_DEFINE_UNIFORM_VECTOR(float, 4, u_scale); -MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, u_pattern_tl_a); -MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, u_pattern_br_a); -MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, u_pattern_tl_b); -MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, u_pattern_br_b); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pattern_size_a); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pattern_size_b); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pixel_coord_upper); -MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pixel_coord_lower); +MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 4, pattern_from); +MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 4, pattern_to); +MBGL_DEFINE_UNIFORM_VECTOR(float, 4, scale); +MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, pattern_tl_a); +MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, pattern_br_a); +MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, pattern_tl_b); +MBGL_DEFINE_UNIFORM_VECTOR(uint16_t, 2, pattern_br_b); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, pattern_size_a); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, pattern_size_b); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, pixel_coord_upper); +MBGL_DEFINE_UNIFORM_VECTOR(float, 2, pixel_coord_lower); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_mix); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale_a); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale_b); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_tile_units_to_pixels); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_overscale_factor); +MBGL_DEFINE_UNIFORM_SCALAR(float, mix); +MBGL_DEFINE_UNIFORM_SCALAR(float, scale_a); +MBGL_DEFINE_UNIFORM_SCALAR(float, scale_b); +MBGL_DEFINE_UNIFORM_SCALAR(float, tile_units_to_pixels); +MBGL_DEFINE_UNIFORM_SCALAR(float, overscale_factor); } // namespace uniforms } // namespace mbgl diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index 398a0b4c0f..13f575ba38 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -11,7 +11,7 @@ namespace mbgl { using namespace style; LineBucket::LineBucket(const style::LineLayoutProperties::PossiblyEvaluated layout_, - std::map<std::string, RenderLinePaintProperties::PossiblyEvaluated> layerPaintProperties, + std::map<std::string, style::LinePaintProperties::PossiblyEvaluated> layerPaintProperties, const float zoom_, const uint32_t overscaling_) : layout(layout_), diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index 6b8d7e786c..7ee8677e50 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -20,7 +20,7 @@ public: // These aliases are used by the PatternLayout template using RenderLayerType = RenderLineLayer; - using PossiblyEvaluatedPaintProperties = RenderLinePaintProperties::PossiblyEvaluated; + using PossiblyEvaluatedPaintProperties = style::LinePaintProperties::PossiblyEvaluated; using PossiblyEvaluatedLayoutProperties = style::LineLayoutProperties::PossiblyEvaluated; LineBucket(const PossiblyEvaluatedLayoutProperties layout, diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index 9220235f1d..68f683c8d6 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -17,7 +17,8 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo bool iconsNeedLinear_, bool sortFeaturesByY_, const std::string bucketName_, - const std::vector<SymbolInstance>&& symbolInstances_) + const std::vector<SymbolInstance>&& symbolInstances_, + float tilePixelRatio_) : layout(std::move(layout_)), sdfIcons(sdfIcons_), iconsNeedLinear(iconsNeedLinear_ || iconSize.isDataDriven() || !iconSize.isZoomConstant()), @@ -25,7 +26,8 @@ SymbolBucket::SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated layo bucketLeaderID(std::move(bucketName_)), symbolInstances(std::move(symbolInstances_)), textSizeBinder(SymbolSizeBinder::create(zoom, textSize, TextSize::defaultValue())), - iconSizeBinder(SymbolSizeBinder::create(zoom, iconSize, IconSize::defaultValue())) { + iconSizeBinder(SymbolSizeBinder::create(zoom, iconSize, IconSize::defaultValue())), + tilePixelRatio(tilePixelRatio_) { for (const auto& pair : paintProperties_) { auto layerPaintProperties = pair.second; @@ -218,12 +220,22 @@ void SymbolBucket::sortFeatures(const float angle) { const SymbolInstance& symbolInstance = symbolInstances[i]; featureSortOrder->push_back(symbolInstance.dataFeatureIndex); - if (symbolInstance.placedTextIndex) { - addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedTextIndex]); + if (symbolInstance.placedRightTextIndex) { + addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedRightTextIndex]); } + + if (symbolInstance.placedCenterTextIndex && !symbolInstance.singleLine) { + addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedCenterTextIndex]); + } + + if (symbolInstance.placedLeftTextIndex && !symbolInstance.singleLine) { + addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedLeftTextIndex]); + } + if (symbolInstance.placedVerticalTextIndex) { addPlacedSymbol(text.triangles, text.placedSymbols[*symbolInstance.placedVerticalTextIndex]); } + if (symbolInstance.placedIconIndex) { addPlacedSymbol(icon.triangles, icon.placedSymbols[*symbolInstance.placedIconIndex]); } diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp index fafa2592fe..f8ffc1a8eb 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.hpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp @@ -35,6 +35,8 @@ public: std::vector<float> glyphOffsets; bool hidden; size_t vertexStartIndex; + // The crossTileID is only filled/used on the foreground for variable text anchors + uint32_t crossTileID = 0u; }; class SymbolBucket final : public Bucket { @@ -48,7 +50,8 @@ public: bool iconsNeedLinear, bool sortFeaturesByY, const std::string bucketLeaderID, - const std::vector<SymbolInstance>&&); + const std::vector<SymbolInstance>&&, + const float tilePixelRatio); ~SymbolBucket() override; void upload(gfx::Context&) override; @@ -130,6 +133,7 @@ public: optional<gfx::IndexBuffer> indexBuffer; } collisionCircle; + const float tilePixelRatio; uint32_t bucketInstanceId = 0; bool justReloaded = false; optional<bool> hasFormatSectionOverrides_; diff --git a/src/mbgl/renderer/image_atlas.cpp b/src/mbgl/renderer/image_atlas.cpp index b39c788ced..282f135ac9 100644 --- a/src/mbgl/renderer/image_atlas.cpp +++ b/src/mbgl/renderer/image_atlas.cpp @@ -1,4 +1,6 @@ #include <mbgl/renderer/image_atlas.hpp> +#include <mbgl/gfx/context.hpp> +#include <mbgl/renderer/image_manager.hpp> #include <mapbox/shelf-pack.hpp> @@ -6,14 +8,15 @@ namespace mbgl { static constexpr uint32_t padding = 1; -ImagePosition::ImagePosition(const mapbox::Bin& bin, const style::Image::Impl& image) +ImagePosition::ImagePosition(const mapbox::Bin& bin, const style::Image::Impl& image, uint32_t version_) : pixelRatio(image.pixelRatio), textureRect( bin.x + padding, bin.y + padding, bin.w - padding * 2, bin.h - padding * 2 - ) { + ), + version(version_) { } const mapbox::Bin& _packImage(mapbox::ShelfPack& pack, const style::Image::Impl& image, ImageAtlas& resultImage, ImageType imageType) { @@ -49,7 +52,30 @@ const mapbox::Bin& _packImage(mapbox::ShelfPack& pack, const style::Image::Impl& return bin; } -ImageAtlas makeImageAtlas(const ImageMap& icons, const ImageMap& patterns) { +void ImageAtlas::patchUpdatedImages(gfx::Context& context, gfx::Texture& atlasTexture, const ImageManager& imageManager) { + for (auto& updatedImageVersion : imageManager.updatedImageVersions) { + auto iconPosition = iconPositions.find(updatedImageVersion.first); + if (iconPosition != iconPositions.end()) { + patchUpdatedImage(context, atlasTexture, iconPosition->second, imageManager, updatedImageVersion.first, updatedImageVersion.second); + } + auto patternPosition = patternPositions.find(updatedImageVersion.first); + if (patternPosition != patternPositions.end()) { + patchUpdatedImage(context, atlasTexture, patternPosition->second, imageManager, updatedImageVersion.first, updatedImageVersion.second); + } + } +} + +void ImageAtlas::patchUpdatedImage(gfx::Context& context, gfx::Texture& atlasTexture, ImagePosition& position, const ImageManager& imageManager, const std::string& name, uint16_t version) { + if (position.version == version) return; + + auto updatedImage = imageManager.getImage(name); + if (updatedImage == nullptr) return; + + context.updateTextureSub(atlasTexture, updatedImage->image, position.textureRect.x, position.textureRect.y); + position.version = version; +} + +ImageAtlas makeImageAtlas(const ImageMap& icons, const ImageMap& patterns, const std::unordered_map<std::string, uint32_t>& versionMap) { ImageAtlas result; mapbox::ShelfPack::ShelfPackOptions options; @@ -59,13 +85,17 @@ ImageAtlas makeImageAtlas(const ImageMap& icons, const ImageMap& patterns) { for (const auto& entry : icons) { const style::Image::Impl& image = *entry.second; const mapbox::Bin& bin = _packImage(pack, image, result, ImageType::Icon); - result.iconPositions.emplace(image.id, ImagePosition { bin, image }); + auto it = versionMap.find(entry.first); + auto version = it != versionMap.end() ? it->second : 0; + result.iconPositions.emplace(image.id, ImagePosition { bin, image, version }); } for (const auto& entry : patterns) { const style::Image::Impl& image = *entry.second; const mapbox::Bin& bin = _packImage(pack, image, result, ImageType::Pattern); - result.patternPositions.emplace(image.id, ImagePosition { bin, image }); + auto it = versionMap.find(entry.first); + auto version = it != versionMap.end() ? it->second : 0; + result.patternPositions.emplace(image.id, ImagePosition { bin, image, version }); } pack.shrink(); diff --git a/src/mbgl/renderer/image_atlas.hpp b/src/mbgl/renderer/image_atlas.hpp index 3af31a75f8..080a490ab2 100644 --- a/src/mbgl/renderer/image_atlas.hpp +++ b/src/mbgl/renderer/image_atlas.hpp @@ -9,12 +9,20 @@ namespace mbgl { +namespace gfx { + class Texture; + class Context; +} // namespace gfx + +class ImageManager; + class ImagePosition { public: - ImagePosition(const mapbox::Bin&, const style::Image::Impl&); + ImagePosition(const mapbox::Bin&, const style::Image::Impl&, uint32_t version = 0); float pixelRatio; Rect<uint16_t> textureRect; + uint32_t version; std::array<uint16_t, 2> tl() const { return {{ @@ -51,8 +59,12 @@ public: PremultipliedImage image; ImagePositions iconPositions; ImagePositions patternPositions; + + void patchUpdatedImages(gfx::Context&, gfx::Texture&, const ImageManager&); +private: + void patchUpdatedImage(gfx::Context&, gfx::Texture&, ImagePosition& position, const ImageManager& imageManager, const std::string& name, uint16_t version); }; -ImageAtlas makeImageAtlas(const ImageMap&, const ImageMap&); +ImageAtlas makeImageAtlas(const ImageMap&, const ImageMap&, const std::unordered_map<std::string, uint32_t>& versionMap); } // namespace mbgl diff --git a/src/mbgl/renderer/image_manager.cpp b/src/mbgl/renderer/image_manager.cpp index 9c9f6c6e08..d2994d6f2d 100644 --- a/src/mbgl/renderer/image_manager.cpp +++ b/src/mbgl/renderer/image_manager.cpp @@ -1,9 +1,16 @@ #include <mbgl/renderer/image_manager.hpp> #include <mbgl/util/logging.hpp> #include <mbgl/gfx/context.hpp> +#include <mbgl/renderer/image_manager_observer.hpp> namespace mbgl { +static ImageManagerObserver nullObserver; + +void ImageManager::setObserver(ImageManagerObserver* observer_) { + observer = observer_ ? observer_ : &nullObserver; +} + void ImageManager::setLoaded(bool loaded_) { if (loaded == loaded_) { return; @@ -13,7 +20,7 @@ void ImageManager::setLoaded(bool loaded_) { if (loaded) { for (const auto& entry : requestors) { - notify(*entry.first, entry.second); + checkMissingAndNotify(*entry.first, entry.second); } requestors.clear(); } @@ -28,9 +35,23 @@ void ImageManager::addImage(Immutable<style::Image::Impl> image_) { images.emplace(image_->id, std::move(image_)); } -void ImageManager::updateImage(Immutable<style::Image::Impl> image_) { +bool ImageManager::updateImage(Immutable<style::Image::Impl> image_) { + auto oldImage = images.find(image_->id); + assert(oldImage != images.end()); + if (oldImage == images.end()) return false; + + auto sizeChanged = oldImage->second->image.size != image_->image.size; + + if (sizeChanged) { + updatedImageVersions.erase(image_->id); + } else { + updatedImageVersions[image_->id]++; + } + removeImage(image_->id); addImage(std::move(image_)); + + return sizeChanged; } void ImageManager::removeImage(const std::string& id) { @@ -60,10 +81,15 @@ const style::Image::Impl* ImageManager::getImage(const std::string& id) const { } void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair) { - // If the sprite has been loaded, or if all the icon dependencies are already present - // (i.e. if they've been addeded via runtime styling), then notify the requestor immediately. - // Otherwise, delay notification until the sprite is loaded. At that point, if any of the - // dependencies are still unavailable, we'll just assume they are permanently missing. + // remove previous requests from this tile + removeRequestor(requestor); + + // If all the icon dependencies are already present ((i.e. if they've been addeded via + // runtime styling), then notify the requestor immediately. Otherwise, if the + // sprite has not loaded, then wait for it. When the sprite has loaded check + // if all icons are available. If any are missing, call `onStyleImageMissing` + // to give the user a chance to provide the icon. If they are not provided + // by the next frame we'll assume they are permanently missing. bool hasAllDependencies = true; if (!isLoaded()) { for (const auto& dependency : pair.first) { @@ -72,29 +98,83 @@ void ImageManager::getImages(ImageRequestor& requestor, ImageRequestPair&& pair) } } } - if (isLoaded() || hasAllDependencies) { - notify(requestor, std::move(pair)); - } else { + + if (hasAllDependencies) { + notify(requestor, pair); + } else if (!isLoaded()) { requestors.emplace(&requestor, std::move(pair)); + } else { + checkMissingAndNotify(requestor, std::move(pair)); } } void ImageManager::removeRequestor(ImageRequestor& requestor) { requestors.erase(&requestor); + missingImageRequestors.erase(&requestor); +} + +void ImageManager::notifyIfMissingImageAdded() { + for (auto it = missingImageRequestors.begin(); it != missingImageRequestors.end();) { + if (it->second.callbacksRemaining == 0) { + notify(*it->first, it->second.pair); + missingImageRequestors.erase(it++); + } else { + it++; + } + } +} + +void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageRequestPair& pair) { + unsigned int missing = 0; + for (const auto& dependency : pair.first) { + auto it = images.find(dependency.first); + if (it == images.end()) { + missing++; + } + } + + if (missing > 0) { + ImageRequestor* requestorPtr = &requestor; + + missingImageRequestors.emplace(requestorPtr, MissingImageRequestPair { std::move(pair), missing }); + + for (const auto& dependency : pair.first) { + auto it = images.find(dependency.first); + if (it == images.end()) { + assert(observer != nullptr); + observer->onStyleImageMissing(dependency.first, [this, requestorPtr]() { + auto requestorIt = missingImageRequestors.find(requestorPtr); + if (requestorIt != missingImageRequestors.end()) { + assert(requestorIt->second.callbacksRemaining > 0); + requestorIt->second.callbacksRemaining--; + } + }); + } + } + + } else { + notify(requestor, pair); + } } void ImageManager::notify(ImageRequestor& requestor, const ImageRequestPair& pair) const { ImageMap iconMap; ImageMap patternMap; + ImageVersionMap versionMap; for (const auto& dependency : pair.first) { auto it = images.find(dependency.first); if (it != images.end()) { dependency.second == ImageType::Pattern ? patternMap.emplace(*it) : iconMap.emplace(*it); + + auto versionIt = updatedImageVersions.find(dependency.first); + if (versionIt != updatedImageVersions.end()) { + versionMap.emplace(versionIt->first, versionIt->second); + } } } - requestor.onImagesAvailable(iconMap, patternMap, pair.second); + requestor.onImagesAvailable(iconMap, patternMap, std::move(versionMap), pair.second); } void ImageManager::dumpDebugLogs() const { diff --git a/src/mbgl/renderer/image_manager.hpp b/src/mbgl/renderer/image_manager.hpp index e56f30ac3f..99887ae384 100644 --- a/src/mbgl/renderer/image_manager.hpp +++ b/src/mbgl/renderer/image_manager.hpp @@ -6,6 +6,7 @@ #include <mbgl/util/immutable.hpp> #include <mbgl/util/optional.hpp> #include <mbgl/gfx/texture.hpp> +#include <mbgl/renderer/image_manager_observer.hpp> #include <mapbox/shelf-pack.hpp> @@ -21,7 +22,7 @@ class Context; class ImageRequestor { public: virtual ~ImageRequestor() = default; - virtual void onImagesAvailable(ImageMap icons, ImageMap patterns, uint64_t imageCorrelationID) = 0; + virtual void onImagesAvailable(ImageMap icons, ImageMap patterns, ImageVersionMap versionMap, uint64_t imageCorrelationID) = 0; }; /* @@ -39,6 +40,8 @@ public: ImageManager(); ~ImageManager(); + void setObserver(ImageManagerObserver*); + void setLoaded(bool); bool isLoaded() const; @@ -47,20 +50,31 @@ public: const style::Image::Impl* getImage(const std::string&) const; void addImage(Immutable<style::Image::Impl>); - void updateImage(Immutable<style::Image::Impl>); + bool updateImage(Immutable<style::Image::Impl>); void removeImage(const std::string&); void getImages(ImageRequestor&, ImageRequestPair&&); void removeRequestor(ImageRequestor&); + void notifyIfMissingImageAdded(); + + ImageVersionMap updatedImageVersions; private: + void checkMissingAndNotify(ImageRequestor&, const ImageRequestPair&); void notify(ImageRequestor&, const ImageRequestPair&) const; bool loaded = false; - std::unordered_map<ImageRequestor*, ImageRequestPair> requestors; + std::map<ImageRequestor*, ImageRequestPair> requestors; + struct MissingImageRequestPair { + ImageRequestPair pair; + unsigned int callbacksRemaining; + }; + std::map<ImageRequestor*, MissingImageRequestPair> missingImageRequestors; ImageMap images; + ImageManagerObserver* observer = nullptr; + // Pattern stuff public: optional<ImagePosition> getPattern(const std::string& name); diff --git a/src/mbgl/renderer/image_manager_observer.hpp b/src/mbgl/renderer/image_manager_observer.hpp new file mode 100644 index 0000000000..3dc53c9b66 --- /dev/null +++ b/src/mbgl/renderer/image_manager_observer.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include <mbgl/renderer/renderer_observer.hpp> + +namespace mbgl { + +class ImageManagerObserver { +public: + virtual ~ImageManagerObserver() = default; + + virtual void onStyleImageMissing(const std::string&, std::function<void()> done) { done(); } +}; + +} // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_background_layer.cpp b/src/mbgl/renderer/layers/render_background_layer.cpp index 32e05a38ab..269b227a7d 100644 --- a/src/mbgl/renderer/layers/render_background_layer.cpp +++ b/src/mbgl/renderer/layers/render_background_layer.cpp @@ -9,7 +9,6 @@ #include <mbgl/util/tile_cover.hpp> #include <mbgl/map/transform_state.hpp> #include <mbgl/gfx/cull_face_mode.hpp> -#include <mbgl/gl/context.hpp> namespace mbgl { @@ -103,7 +102,7 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { parameters.state ), BackgroundPatternProgram::TextureBindings{ - textures::u_image::Value{ parameters.imageManager.textureBinding(parameters.context) }, + textures::image::Value{ parameters.imageManager.textureBinding(parameters.context) }, } ); } @@ -112,9 +111,9 @@ void RenderBackgroundLayer::render(PaintParameters& parameters, RenderSource*) { draw( parameters.programs.getBackgroundLayerPrograms().background, BackgroundProgram::LayoutUniformValues { - uniforms::u_matrix::Value( parameters.matrixForTile(tileID) ), - uniforms::u_color::Value( evaluated.get<BackgroundColor>() ), - uniforms::u_opacity::Value( evaluated.get<BackgroundOpacity>() ), + uniforms::matrix::Value( parameters.matrixForTile(tileID) ), + uniforms::color::Value( evaluated.get<BackgroundColor>() ), + uniforms::opacity::Value( evaluated.get<BackgroundOpacity>() ), }, BackgroundProgram::TextureBindings{} ); diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index 60a3bf8e01..1c13a6152b 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -8,7 +8,6 @@ #include <mbgl/style/layers/circle_layer_impl.hpp> #include <mbgl/geometry/feature_index.hpp> #include <mbgl/gfx/cull_face_mode.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> @@ -66,23 +65,23 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) { const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); - auto& programInstance = parameters.programs.getCircleLayerPrograms().circle.get(evaluated); + auto& programInstance = parameters.programs.getCircleLayerPrograms().circle; const auto allUniformValues = programInstance.computeAllUniformValues( CircleProgram::LayoutUniformValues { - uniforms::u_matrix::Value( + uniforms::matrix::Value( tile.translatedMatrix(evaluated.get<CircleTranslate>(), evaluated.get<CircleTranslateAnchor>(), parameters.state) ), - uniforms::u_scale_with_map::Value( scaleWithMap ), - uniforms::u_extrude_scale::Value( pitchWithMap + uniforms::scale_with_map::Value( scaleWithMap ), + uniforms::extrude_scale::Value( pitchWithMap ? std::array<float, 2> {{ tile.id.pixelsToTileUnits(1, parameters.state.getZoom()), tile.id.pixelsToTileUnits(1, parameters.state.getZoom()) }} : parameters.pixelsToGLUnits ), - uniforms::u_camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ), - uniforms::u_pitch_with_map::Value( pitchWithMap ) + uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ), + uniforms::pitch_with_map::Value( pitchWithMap ) }, paintPropertyBinders, evaluated, diff --git a/src/mbgl/renderer/layers/render_custom_layer.cpp b/src/mbgl/renderer/layers/render_custom_layer.cpp index bcb0decb74..8ac7d29ff6 100644 --- a/src/mbgl/renderer/layers/render_custom_layer.cpp +++ b/src/mbgl/renderer/layers/render_custom_layer.cpp @@ -57,7 +57,8 @@ void RenderCustomLayer::render(PaintParameters& paintParameters, RenderSource*) MBGL_CHECK_ERROR(host->initialize()); } - gl::Context& glContext = paintParameters.context; + // TODO: remove cast + gl::Context& glContext = reinterpret_cast<gl::Context&>(paintParameters.context); const TransformState& state = paintParameters.state; // Reset GL state to a known state so the CustomLayer always has a clean slate. diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index 5af4732aa3..13ef84f169 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -51,6 +51,9 @@ bool RenderFillExtrusionLayer::hasCrossfade() const { } void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource*) { + // TODO: remove cast + gl::Context& glContext = reinterpret_cast<gl::Context&>(parameters.context); + if (parameters.pass == RenderPass::Opaque) { return; } @@ -69,8 +72,8 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* // Flag the depth buffer as no longer needing to be cleared for the remainder of this pass. parameters.staticData.depthRenderbuffer->shouldClear(false); - parameters.context.setStencilMode(gfx::StencilMode::disabled()); - parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, depthClearValue, {}); + glContext.setStencilMode(gfx::StencilMode::disabled()); + glContext.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, depthClearValue, {}); auto draw = [&](auto& programInstance, const auto& tileBucket, auto&& uniformValues, const optional<ImagePosition>& patternPositionA, @@ -116,7 +119,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* FillExtrusionBucket& bucket = *bucket_; draw( - parameters.programs.getFillExtrusionLayerPrograms().fillExtrusion.get(evaluated), + parameters.programs.getFillExtrusionLayerPrograms().fillExtrusion, bucket, FillExtrusionProgram::layoutUniformValues( tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), @@ -143,7 +146,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* FillExtrusionBucket& bucket = *bucket_; draw( - parameters.programs.getFillExtrusionLayerPrograms().fillExtrusionPattern.get(evaluated), + parameters.programs.getFillExtrusionLayerPrograms().fillExtrusionPattern, bucket, FillExtrusionPatternProgram::layoutUniformValues( tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), @@ -160,7 +163,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* patternPosA, patternPosB, FillExtrusionPatternProgram::TextureBindings{ - textures::u_image::Value{ *geometryTile.iconAtlasTexture->resource, gfx::TextureFilterType::Linear }, + textures::image::Value{ *geometryTile.iconAtlasTexture->resource, gfx::TextureFilterType::Linear }, } ); } @@ -179,9 +182,9 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* const auto allUniformValues = programInstance.computeAllUniformValues( ExtrusionTextureProgram::LayoutUniformValues{ - uniforms::u_matrix::Value( viewportMat ), - uniforms::u_world::Value( size ), - uniforms::u_opacity::Value( evaluated.get<FillExtrusionOpacity>() ) + uniforms::matrix::Value( viewportMat ), + uniforms::world::Value( size ), + uniforms::opacity::Value( evaluated.get<FillExtrusionOpacity>() ) }, paintAttributeData, properties, @@ -207,7 +210,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* allUniformValues, allAttributeBindings, ExtrusionTextureProgram::TextureBindings{ - textures::u_image::Value{ *renderTexture->getTexture().resource }, + textures::image::Value{ *renderTexture->getTexture().resource }, }, getID()); } diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index 64f3448c69..205a38e380 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -63,6 +63,9 @@ bool RenderFillLayer::hasCrossfade() const { } void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { + // TODO: remove cast + gl::Context& glContext = reinterpret_cast<gl::Context&>(parameters.context); + if (unevaluated.get<FillPattern>().isUndefined()) { for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillBucket>(*baseImpl); @@ -71,24 +74,22 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { } FillBucket& bucket = *bucket_; - auto draw = [&] (auto& program, + auto draw = [&] (auto& programInstance, const auto& drawMode, const auto& depthMode, const auto& indexBuffer, const auto& segments, auto&& textureBindings) { - auto& programInstance = program.get(evaluated); - const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); const auto allUniformValues = programInstance.computeAllUniformValues( FillProgram::LayoutUniformValues { - uniforms::u_matrix::Value( + uniforms::matrix::Value( tile.translatedMatrix(evaluated.get<FillTranslate>(), evaluated.get<FillTranslateAnchor>(), parameters.state) ), - uniforms::u_world::Value( parameters.context.viewport.getCurrentValue().size ), + uniforms::world::Value( glContext.viewport.getCurrentValue().size ), }, paintPropertyBinders, evaluated, @@ -159,14 +160,12 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { } FillBucket& bucket = *bucket_; - auto draw = [&] (auto& program, + auto draw = [&] (auto& programInstance, const auto& drawMode, const auto& depthMode, const auto& indexBuffer, const auto& segments, auto&& textureBindings) { - auto& programInstance = program.get(evaluated); - const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade); @@ -175,7 +174,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { tile.translatedMatrix(evaluated.get<FillTranslate>(), evaluated.get<FillTranslateAnchor>(), parameters.state), - parameters.context.viewport.getCurrentValue().size, + glContext.viewport.getCurrentValue().size, geometryTile.iconAtlasTexture->size, crossfade, tile.id, @@ -216,7 +215,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { *bucket.triangleIndexBuffer, bucket.triangleSegments, FillPatternProgram::TextureBindings{ - textures::u_image::Value{ *geometryTile.iconAtlasTexture->resource, gfx::TextureFilterType::Linear }, + textures::image::Value{ *geometryTile.iconAtlasTexture->resource, gfx::TextureFilterType::Linear }, }); if (evaluated.get<FillAntialias>() && unevaluated.get<FillOutlineColor>().isUndefined()) { @@ -226,7 +225,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { *bucket.lineIndexBuffer, bucket.lineSegments, FillOutlinePatternProgram::TextureBindings{ - textures::u_image::Value{ *geometryTile.iconAtlasTexture->resource, gfx::TextureFilterType::Linear }, + textures::image::Value{ *geometryTile.iconAtlasTexture->resource, gfx::TextureFilterType::Linear }, }); } } diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index efc16fb28a..f8ba68965e 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -52,12 +52,15 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { return; } + // TODO: remove cast + gl::Context& glContext = reinterpret_cast<gl::Context&>(parameters.context); + if (parameters.pass == RenderPass::Pass3D) { const auto& viewportSize = parameters.staticData.backendSize; const auto size = Size{viewportSize.width / 4, viewportSize.height / 4}; if (!renderTexture || renderTexture->getSize() != size) { - if (parameters.context.supportsHalfFloatTextures) { + if (glContext.supportsHalfFloatTextures) { renderTexture = OffscreenTexture(parameters.context, size, gfx::TextureChannelDataType::HalfFloat); try { @@ -65,11 +68,11 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { } catch (const std::runtime_error& ex) { // can't render to a half-float texture; falling back to unsigned byte one renderTexture = nullopt; - parameters.context.supportsHalfFloatTextures = false; + glContext.supportsHalfFloatTextures = false; } } - if (!parameters.context.supportsHalfFloatTextures || !renderTexture) { + if (!glContext.supportsHalfFloatTextures || !renderTexture) { renderTexture = OffscreenTexture(parameters.context, size, gfx::TextureChannelDataType::UnsignedByte); renderTexture->bind(); } @@ -82,7 +85,7 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { colorRampTexture = parameters.context.createTexture(colorRamp, gfx::TextureChannelDataType::UnsignedByte); } - parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 1.0f }, {}, {}); + glContext.clear(Color{ 0.0f, 0.0f, 0.0f, 1.0f }, {}, {}); for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<HeatmapBucket>(*baseImpl); @@ -99,13 +102,13 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); - auto& programInstance = parameters.programs.getHeatmapLayerPrograms().heatmap.get(evaluated); + auto& programInstance = parameters.programs.getHeatmapLayerPrograms().heatmap; const auto allUniformValues = programInstance.computeAllUniformValues( HeatmapProgram::LayoutUniformValues { - uniforms::u_intensity::Value( evaluated.get<style::HeatmapIntensity>() ), - uniforms::u_matrix::Value( tile.matrix ), - uniforms::heatmap::u_extrude_scale::Value( extrudeScale ) + uniforms::intensity::Value( evaluated.get<style::HeatmapIntensity>() ), + uniforms::matrix::Value( tile.matrix ), + uniforms::heatmap::extrude_scale::Value( extrudeScale ) }, paintPropertyBinders, evaluated, @@ -148,9 +151,9 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto allUniformValues = programInstance.computeAllUniformValues( HeatmapTextureProgram::LayoutUniformValues{ - uniforms::u_matrix::Value( viewportMat ), - uniforms::u_world::Value( size ), - uniforms::u_opacity::Value( evaluated.get<HeatmapOpacity>() ) + uniforms::matrix::Value( viewportMat ), + uniforms::world::Value( size ), + uniforms::opacity::Value( evaluated.get<HeatmapOpacity>() ) }, paintAttributeData, properties, @@ -176,8 +179,8 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { allUniformValues, allAttributeBindings, HeatmapTextureProgram::TextureBindings{ - textures::u_image::Value{ *renderTexture->getTexture().resource, gfx::TextureFilterType::Linear }, - textures::u_color_ramp::Value{ *colorRampTexture->resource, gfx::TextureFilterType::Linear }, + textures::image::Value{ *renderTexture->getTexture().resource, gfx::TextureFilterType::Linear }, + textures::color_ramp::Value{ *colorRampTexture->resource, gfx::TextureFilterType::Linear }, }, getID() ); diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index 00ecad444c..1d030f5946 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -10,7 +10,6 @@ #include <mbgl/tile/tile.hpp> #include <mbgl/style/layers/hillshade_layer_impl.hpp> #include <mbgl/gfx/cull_face_mode.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/util/geo.hpp> #include <mbgl/util/offscreen_texture.hpp> @@ -77,12 +76,12 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src const auto allUniformValues = programInstance.computeAllUniformValues( HillshadeProgram::LayoutUniformValues { - uniforms::u_matrix::Value( matrix ), - uniforms::u_highlight::Value( evaluated.get<HillshadeHighlightColor>() ), - uniforms::u_shadow::Value( evaluated.get<HillshadeShadowColor>() ), - uniforms::u_accent::Value( evaluated.get<HillshadeAccentColor>() ), - uniforms::u_light::Value( getLight(parameters) ), - uniforms::u_latrange::Value( getLatRange(id) ), + uniforms::matrix::Value( matrix ), + uniforms::highlight::Value( evaluated.get<HillshadeHighlightColor>() ), + uniforms::shadow::Value( evaluated.get<HillshadeShadowColor>() ), + uniforms::accent::Value( evaluated.get<HillshadeAccentColor>() ), + uniforms::light::Value( getLight(parameters) ), + uniforms::latrange::Value( getLatRange(id) ), }, paintAttributeData, evaluated, @@ -141,10 +140,10 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src const auto allUniformValues = programInstance.computeAllUniformValues( HillshadePrepareProgram::LayoutUniformValues { - uniforms::u_matrix::Value( mat ), - uniforms::u_dimension::Value( {{stride, stride}} ), - uniforms::u_zoom::Value( float(tile.id.canonical.z) ), - uniforms::u_maxzoom::Value( float(maxzoom) ), + uniforms::matrix::Value( mat ), + uniforms::dimension::Value( {{stride, stride}} ), + uniforms::zoom::Value( float(tile.id.canonical.z) ), + uniforms::maxzoom::Value( float(maxzoom) ), }, paintAttributeData, properties, @@ -170,7 +169,7 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src allUniformValues, allAttributeBindings, HillshadePrepareProgram::TextureBindings{ - textures::u_image::Value{ *bucket.dem->resource }, + textures::image::Value{ *bucket.dem->resource }, }, getID() ); @@ -187,7 +186,7 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src bucket.segments, tile.id, HillshadeProgram::TextureBindings{ - textures::u_image::Value{ *bucket.texture->resource, gfx::TextureFilterType::Linear }, + textures::image::Value{ *bucket.texture->resource, gfx::TextureFilterType::Linear }, }); } else { // Draw the full tile. @@ -197,7 +196,7 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src parameters.staticData.rasterSegments, tile.id, HillshadeProgram::TextureBindings{ - textures::u_image::Value{ *bucket.texture->resource, gfx::TextureFilterType::Linear }, + textures::image::Value{ *bucket.texture->resource, gfx::TextureFilterType::Linear }, }); } } diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index eee151ccaa..2d246df7f4 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -9,7 +9,6 @@ #include <mbgl/tile/tile.hpp> #include <mbgl/style/layers/line_layer_impl.hpp> #include <mbgl/gfx/cull_face_mode.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/geometry/feature_index.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> @@ -34,10 +33,7 @@ void RenderLineLayer::transition(const TransitionParameters& parameters) { } void RenderLineLayer::evaluate(const PropertyEvaluationParameters& parameters) { - style::Properties<LineFloorwidth>::Unevaluated extra(unevaluated.get<style::LineWidth>()); - evaluated = RenderLinePaintProperties::PossiblyEvaluated( - unevaluated.evaluate(parameters).concat(extra.evaluate(parameters))); - + evaluated = unevaluated.evaluate(parameters); crossfade = parameters.getCrossfadeParameters(); passes = (evaluated.get<style::LineOpacity>().constantOr(1.0) > 0 @@ -66,11 +62,10 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { } LineBucket& bucket = *bucket_; - auto draw = [&](auto& program, auto&& uniformValues, + auto draw = [&](auto& programInstance, + auto&& uniformValues, const optional<ImagePosition>& patternPositionA, const optional<ImagePosition>& patternPositionB, auto&& textureBindings) { - auto& programInstance = program.get(evaluated); - const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade); @@ -145,10 +140,10 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { texsize, crossfade, parameters.pixelRatio), - *posA, - *posB, + posA, + posB, LinePatternProgram::TextureBindings{ - textures::u_image::Value{ *geometryTile.iconAtlasTexture->resource, gfx::TextureFilterType::Linear }, + textures::image::Value{ *geometryTile.iconAtlasTexture->resource, gfx::TextureFilterType::Linear }, }); } else if (!unevaluated.get<LineGradient>().getValue().isUndefined()) { if (!colorRampTexture) { @@ -164,7 +159,7 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { {}, {}, LineGradientProgram::TextureBindings{ - textures::u_image::Value{ *colorRampTexture->resource, gfx::TextureFilterType::Linear }, + textures::image::Value{ *colorRampTexture->resource, gfx::TextureFilterType::Linear }, }); } else { draw(parameters.programs.getLineLayerPrograms().line, diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp index 186b740234..cb4492ebc3 100644 --- a/src/mbgl/renderer/layers/render_line_layer.hpp +++ b/src/mbgl/renderer/layers/render_line_layer.hpp @@ -10,15 +10,6 @@ namespace mbgl { -struct LineFloorwidth : style::DataDrivenPaintProperty<float, attributes::a_floorwidth, uniforms::u_floorwidth> { - using EvaluatorType = DataDrivenPropertyEvaluator<float, true>; - static float defaultValue() { return 1.0; } -}; - -class RenderLinePaintProperties : public style::ConcatenateProperties< - style::LinePaintProperties, - style::Properties<LineFloorwidth>> {}; - class RenderLineLayer: public RenderLayer { public: using StyleLayerImpl = style::LineLayer::Impl; @@ -44,7 +35,7 @@ public: // Paint properties style::LinePaintProperties::Unevaluated unevaluated; - RenderLinePaintProperties::PossiblyEvaluated evaluated; + style::LinePaintProperties::PossiblyEvaluated evaluated; const style::LineLayer::Impl& impl() const; diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp index c8f00eb1fd..94c4a8dc42 100644 --- a/src/mbgl/renderer/layers/render_raster_layer.cpp +++ b/src/mbgl/renderer/layers/render_raster_layer.cpp @@ -8,7 +8,6 @@ #include <mbgl/programs/raster_program.hpp> #include <mbgl/tile/tile.hpp> #include <mbgl/gfx/cull_face_mode.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/style/layers/raster_layer_impl.hpp> namespace mbgl { @@ -85,17 +84,17 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source const auto allUniformValues = programInstance.computeAllUniformValues( RasterProgram::LayoutUniformValues { - uniforms::u_matrix::Value( matrix ), - uniforms::u_opacity::Value( evaluated.get<RasterOpacity>() ), - uniforms::u_fade_t::Value( 1 ), - uniforms::u_brightness_low::Value( evaluated.get<RasterBrightnessMin>() ), - uniforms::u_brightness_high::Value( evaluated.get<RasterBrightnessMax>() ), - uniforms::u_saturation_factor::Value( saturationFactor(evaluated.get<RasterSaturation>()) ), - uniforms::u_contrast_factor::Value( contrastFactor(evaluated.get<RasterContrast>()) ), - uniforms::u_spin_weights::Value( spinWeights(evaluated.get<RasterHueRotate>()) ), - uniforms::u_buffer_scale::Value( 1.0f ), - uniforms::u_scale_parent::Value( 1.0f ), - uniforms::u_tl_parent::Value( std::array<float, 2> {{ 0.0f, 0.0f }} ), + uniforms::matrix::Value( matrix ), + uniforms::opacity::Value( evaluated.get<RasterOpacity>() ), + uniforms::fade_t::Value( 1 ), + uniforms::brightness_low::Value( evaluated.get<RasterBrightnessMin>() ), + uniforms::brightness_high::Value( evaluated.get<RasterBrightnessMax>() ), + uniforms::saturation_factor::Value( saturationFactor(evaluated.get<RasterSaturation>()) ), + uniforms::contrast_factor::Value( contrastFactor(evaluated.get<RasterContrast>()) ), + uniforms::spin_weights::Value( spinWeights(evaluated.get<RasterHueRotate>()) ), + uniforms::buffer_scale::Value( 1.0f ), + uniforms::scale_parent::Value( 1.0f ), + uniforms::tl_parent::Value( std::array<float, 2> {{ 0.0f, 0.0f }} ), }, paintAttributeData, evaluated, @@ -138,8 +137,8 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source *bucket.indexBuffer, bucket.segments, RasterProgram::TextureBindings{ - textures::u_image0::Value{ *bucket.texture->resource, filter }, - textures::u_image1::Value{ *bucket.texture->resource, filter }, + textures::image0::Value{ *bucket.texture->resource, filter }, + textures::image1::Value{ *bucket.texture->resource, filter }, }); } } @@ -162,8 +161,8 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source *bucket.indexBuffer, bucket.segments, RasterProgram::TextureBindings{ - textures::u_image0::Value{ *bucket.texture->resource, filter }, - textures::u_image1::Value{ *bucket.texture->resource, filter }, + textures::image0::Value{ *bucket.texture->resource, filter }, + textures::image1::Value{ *bucket.texture->resource, filter }, }); } else { // Draw the full tile. @@ -172,8 +171,8 @@ void RenderRasterLayer::render(PaintParameters& parameters, RenderSource* source parameters.staticData.quadTriangleIndexBuffer, parameters.staticData.rasterSegments, RasterProgram::TextureBindings{ - textures::u_image0::Value{ *bucket.texture->resource, filter }, - textures::u_image1::Value{ *bucket.texture->resource, filter }, + textures::image0::Value{ *bucket.texture->resource, filter }, + textures::image1::Value{ *bucket.texture->resource, filter }, }); } } diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 31d92dd414..d7951c647a 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -5,6 +5,7 @@ #include <mbgl/renderer/render_tile.hpp> #include <mbgl/renderer/paint_parameters.hpp> #include <mbgl/text/glyph_atlas.hpp> +#include <mbgl/text/shaping.hpp> #include <mbgl/programs/programs.hpp> #include <mbgl/programs/symbol_program.hpp> #include <mbgl/programs/collision_box_program.hpp> @@ -13,8 +14,8 @@ #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> #include <mbgl/gfx/cull_face_mode.hpp> -#include <mbgl/gl/context.hpp> #include <mbgl/layout/symbol_projection.hpp> +#include <mbgl/layout/symbol_layout.hpp> #include <mbgl/util/math.hpp> #include <cmath> @@ -23,6 +24,19 @@ namespace mbgl { using namespace style; +namespace { +Point<float> calculateVariableRenderShift(style::SymbolAnchorType anchor, float width, float height, float radialOffset, float textBoxScale, float renderTextSize) { + AnchorAlignment alignment = AnchorAlignment::getAnchorAlignment(anchor); + float shiftX = -(alignment.horizontalAlign - 0.5f) * width; + float shiftY = -(alignment.verticalAlign - 0.5f) * height; + Point<float> offset = SymbolLayout::evaluateRadialOffset(anchor, radialOffset); + return Point<float>( + (shiftX / textBoxScale + offset.x) * renderTextSize, + (shiftY / textBoxScale + offset.y) * renderTextSize + ); +} +} // namespace + RenderSymbolLayer::RenderSymbolLayer(Immutable<style::SymbolLayer::Impl> _impl) : RenderLayer(std::move(_impl)), unevaluated(impl().paint.untransitioned()) { @@ -89,17 +103,14 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { const auto& evaluated_ = bucketPaintProperties.evaluated; const auto& layout = bucket.layout; - auto draw = [&] (auto& program, + auto draw = [&] (auto& programInstance, auto&& uniformValues, const auto& buffers, const auto& symbolSizeBinder, const SymbolPropertyValues& values_, const auto& binders, const auto& paintProperties, - auto&& textureBindings) - { - auto& programInstance = program.get(paintProperties); - + auto&& textureBindings) { const auto allUniformValues = programInstance.computeAllUniformValues( std::move(uniformValues), *symbolSizeBinder, @@ -172,7 +183,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { if (bucket.sdfIcons) { if (values.hasHalo) { draw(parameters.programs.getSymbolLayerPrograms().symbolIconSDF, - SymbolSDFIconProgram::layoutUniformValues(false, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Halo), + SymbolSDFIconProgram::layoutUniformValues(false, false, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Halo), bucket.icon, bucket.iconSizeBinder, values, @@ -185,7 +196,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { if (values.hasFill) { draw(parameters.programs.getSymbolLayerPrograms().symbolIconSDF, - SymbolSDFIconProgram::layoutUniformValues(false, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Fill), + SymbolSDFIconProgram::layoutUniformValues(false, false, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Fill), bucket.icon, bucket.iconSizeBinder, values, @@ -197,7 +208,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { } } else { draw(parameters.programs.getSymbolLayerPrograms().symbolIcon, - SymbolIconProgram::layoutUniformValues(false, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange), + SymbolIconProgram::layoutUniformValues(false, false, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange), bucket.icon, bucket.iconSizeBinder, values, @@ -215,6 +226,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { auto values = textPropertyValues(evaluated_, layout); const auto& paintPropertyValues = textPaintProperties(evaluated_); + bool hasVariablePacement = false; const bool alongLine = layout.get<SymbolPlacement>() != SymbolPlacementType::Point && layout.get<TextRotationAlignment>() == AlignmentType::Map; @@ -229,13 +241,79 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { parameters.state); parameters.context.updateVertexBuffer(*bucket.text.dynamicVertexBuffer, std::move(bucket.text.dynamicVertices)); + } else if (!layout.get<TextVariableAnchor>().empty()) { + bucket.text.dynamicVertices.clear(); + + const auto partiallyEvaluatedSize = bucket.textSizeBinder->evaluateForZoom(parameters.state.getZoom()); + const float tileScale = std::pow(2, parameters.state.getZoom() - tile.tile.id.overscaledZ); + const bool rotateWithMap = layout.get<TextRotationAlignment>() == AlignmentType::Map; + const bool pitchWithMap = layout.get<TextPitchAlignment>() == AlignmentType::Map; + const float pixelsToTileUnits = tile.id.pixelsToTileUnits(1.0, parameters.state.getZoom()); + const auto labelPlaneMatrix = getLabelPlaneMatrix(tile.matrix, pitchWithMap, rotateWithMap, parameters.state, pixelsToTileUnits); + + for (const PlacedSymbol& symbol : bucket.text.placedSymbols) { + optional<VariableOffset> variableOffset; + if (!symbol.hidden && symbol.crossTileID != 0u) { + auto it = parameters.variableOffsets.get().find(symbol.crossTileID); + if (it != parameters.variableOffsets.get().end()) { + variableOffset = it->second; + hasVariablePacement |= true; + } + } + + if (!variableOffset) { + // These symbols are from a justification that is not being used, or a label that wasn't placed + // so we don't need to do the extra math to figure out what incremental shift to apply. + hideGlyphs(symbol.glyphOffsets.size(), bucket.text.dynamicVertices); + } else { + const Point<float> tileAnchor = symbol.anchorPoint; + const auto projectedAnchor = project(tileAnchor, pitchWithMap ? tile.matrix : labelPlaneMatrix); + const float perspectiveRatio = 0.5f + 0.5f * (parameters.state.getCameraToCenterDistance() / projectedAnchor.second); + float renderTextSize = evaluateSizeForFeature(partiallyEvaluatedSize, symbol) * perspectiveRatio / util::ONE_EM; + if (pitchWithMap) { + // Go from size in pixels to equivalent size in tile units + renderTextSize *= bucket.tilePixelRatio / tileScale; + } + + auto shift = calculateVariableRenderShift( + (*variableOffset).anchor, + (*variableOffset).width, + (*variableOffset).height, + (*variableOffset).radialOffset, + (*variableOffset).textBoxScale, + renderTextSize); + + // Usual case is that we take the projected anchor and add the pixel-based shift + // calculated above. In the (somewhat weird) case of pitch-aligned text, we add an equivalent + // tile-unit based shift to the anchor before projecting to the label plane. + Point<float> shiftedAnchor; + if (pitchWithMap) { + shiftedAnchor = project(Point<float>(tileAnchor.x + shift.x, tileAnchor.y + shift.y), + labelPlaneMatrix).first; + } else { + if (rotateWithMap) { + auto rotated = util::rotate(shift, -parameters.state.getPitch()); + shiftedAnchor = Point<float>(projectedAnchor.first.x + rotated.x, + projectedAnchor.first.y + rotated.y); + } else { + shiftedAnchor = Point<float>(projectedAnchor.first.x + shift.x, + projectedAnchor.first.y + shift.y); + } + } + + for (std::size_t i = 0; i < symbol.glyphOffsets.size(); i++) { + addDynamicAttributes(shiftedAnchor, 0, bucket.text.dynamicVertices); + } + } + } + parameters.context.updateVertexBuffer(*bucket.text.dynamicVertexBuffer, std::move(bucket.text.dynamicVertices)); } const Size texsize = geometryTile.glyphAtlasTexture->size; if (values.hasHalo) { draw(parameters.programs.getSymbolLayerPrograms().symbolGlyph, - SymbolSDFTextProgram::layoutUniformValues(true, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Halo), + SymbolSDFTextProgram::layoutUniformValues(true, hasVariablePacement, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Halo), bucket.text, bucket.textSizeBinder, values, @@ -248,7 +326,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { if (values.hasFill) { draw(parameters.programs.getSymbolLayerPrograms().symbolGlyph, - SymbolSDFTextProgram::layoutUniformValues(true, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Fill), + SymbolSDFTextProgram::layoutUniformValues(true, hasVariablePacement, values, texsize, parameters.pixelsToGLUnits, alongLine, tile, parameters.state, parameters.symbolFadeChange, SymbolSDFPart::Fill), bucket.text, bucket.textSizeBinder, values, @@ -280,9 +358,9 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), CollisionBoxProgram::LayoutUniformValues { - uniforms::u_matrix::Value( tile.matrix ), - uniforms::u_extrude_scale::Value( extrudeScale ), - uniforms::u_camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ) + uniforms::matrix::Value( tile.matrix ), + uniforms::extrude_scale::Value( extrudeScale ), + uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ) }, *bucket.collisionBox.vertexBuffer, *bucket.collisionBox.dynamicVertexBuffer, @@ -316,10 +394,10 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { parameters.colorModeForRenderPass(), gfx::CullFaceMode::disabled(), CollisionCircleProgram::LayoutUniformValues { - uniforms::u_matrix::Value( tile.matrix ), - uniforms::u_extrude_scale::Value( extrudeScale ), - uniforms::u_overscale_factor::Value( float(tile.tile.id.overscaleFactor()) ), - uniforms::u_camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ) + uniforms::matrix::Value( tile.matrix ), + uniforms::extrude_scale::Value( extrudeScale ), + uniforms::overscale_factor::Value( float(tile.tile.id.overscaleFactor()) ), + uniforms::camera_to_center_distance::Value( parameters.state.getCameraToCenterDistance() ) }, *bucket.collisionCircle.vertexBuffer, *bucket.collisionCircle.dynamicVertexBuffer, @@ -392,12 +470,9 @@ style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::S }; } -RenderLayer::RenderTiles RenderSymbolLayer::filterRenderTiles(RenderTiles tiles) const { +void RenderSymbolLayer::setRenderTiles(RenderTiles tiles, const TransformState& state) { auto filterFn = [](auto& tile){ return !tile.tile.isRenderable(); }; - return RenderLayer::filterRenderTiles(std::move(tiles), filterFn); -} - -void RenderSymbolLayer::sortRenderTiles(const TransformState& state) { + renderTiles = RenderLayer::filterRenderTiles(std::move(tiles), filterFn); // Sort symbol tiles in opposite y position, so tiles with overlapping symbols are drawn // on top of each other, with lower symbols being drawn on top of higher symbols. std::sort(renderTiles.begin(), renderTiles.end(), [&state](const auto& a, const auto& b) { diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index e44ad398f4..4de5c8538a 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -57,7 +57,7 @@ class BucketParameters; class SymbolLayout; class GeometryTileLayer; -class RenderSymbolLayer: public RenderLayer, public RenderLayerSymbolInterface { +class RenderSymbolLayer final: public RenderLayer, public RenderLayerSymbolInterface { public: RenderSymbolLayer(Immutable<style::SymbolLayer::Impl>); ~RenderSymbolLayer() final = default; @@ -67,6 +67,7 @@ public: bool hasTransition() const override; bool hasCrossfade() const override; void render(PaintParameters&, RenderSource*) override; + void setRenderTiles(RenderTiles, const TransformState&) override; static style::IconPaintProperties::PossiblyEvaluated iconPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated&); static style::TextPaintProperties::PossiblyEvaluated textPaintProperties(const style::SymbolPaintProperties::PossiblyEvaluated&); @@ -91,8 +92,6 @@ protected: const style::SymbolLayoutProperties::PossiblyEvaluated&); static style::SymbolPropertyValues textPropertyValues(const style::SymbolPaintProperties::PossiblyEvaluated&, const style::SymbolLayoutProperties::PossiblyEvaluated&); - RenderTiles filterRenderTiles(RenderTiles) const final; - void sortRenderTiles(const TransformState&) final; void updateBucketPaintProperties(Bucket*) const final; }; diff --git a/src/mbgl/renderer/paint_parameters.cpp b/src/mbgl/renderer/paint_parameters.cpp index 2237b016d2..55dbf70472 100644 --- a/src/mbgl/renderer/paint_parameters.cpp +++ b/src/mbgl/renderer/paint_parameters.cpp @@ -5,7 +5,7 @@ namespace mbgl { -PaintParameters::PaintParameters(gl::Context& context_, +PaintParameters::PaintParameters(gfx::Context& context_, float pixelRatio_, GLContextMode contextMode_, RendererBackend& backend_, @@ -13,7 +13,8 @@ PaintParameters::PaintParameters(gl::Context& context_, const EvaluatedLight& evaluatedLight_, RenderStaticData& staticData_, ImageManager& imageManager_, - LineAtlas& lineAtlas_) + LineAtlas& lineAtlas_, + Placement::VariableOffsets variableOffsets_) : context(context_), backend(backend_), state(updateParameters.transformState), @@ -26,6 +27,7 @@ PaintParameters::PaintParameters(gl::Context& context_, contextMode(contextMode_), timePoint(updateParameters.timePoint), pixelRatio(pixelRatio_), + variableOffsets(variableOffsets_), #ifndef NDEBUG programs((debugOptions & MapDebugOptions::Overdraw) ? staticData_.overdrawPrograms : staticData_.programs) #else diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp index ea3b41adfe..537158a68e 100644 --- a/src/mbgl/renderer/paint_parameters.hpp +++ b/src/mbgl/renderer/paint_parameters.hpp @@ -9,6 +9,7 @@ #include <mbgl/gfx/color_mode.hpp> #include <mbgl/util/mat4.hpp> #include <mbgl/algorithm/generate_clip_ids.hpp> +#include <mbgl/text/placement.hpp> #include <array> @@ -23,13 +24,13 @@ class ImageManager; class LineAtlas; class UnwrappedTileID; -namespace gl { +namespace gfx { class Context; -} // namespace gl +} // namespace gfx class PaintParameters { public: - PaintParameters(gl::Context&, + PaintParameters(gfx::Context&, float pixelRatio, GLContextMode, RendererBackend&, @@ -37,9 +38,10 @@ public: const EvaluatedLight&, RenderStaticData&, ImageManager&, - LineAtlas&); + LineAtlas&, + Placement::VariableOffsets); - gl::Context& context; + gfx::Context& context; RendererBackend& backend; const TransformState& state; @@ -56,6 +58,7 @@ public: TimePoint timePoint; float pixelRatio; + Placement::VariableOffsets variableOffsets; std::array<float, 2> pixelsToGLUnits; algorithm::ClipIDGenerator clipIDGenerator; diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index a014b36ece..dd56afb2e8 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -4,6 +4,7 @@ #include <mbgl/gfx/uniform.hpp> #include <mbgl/gfx/attribute.hpp> #include <mbgl/programs/attributes.hpp> +#include <mbgl/util/literal.hpp> #include <mbgl/util/type_list.hpp> #include <mbgl/renderer/possibly_evaluated_property_value.hpp> #include <mbgl/renderer/paint_property_statistics.hpp> @@ -147,7 +148,7 @@ public: void upload(gfx::Context&) override {} void setPatternParameters(const optional<ImagePosition>& posA, const optional<ImagePosition>& posB, CrossfadeParameters&) override { - if (!posA && !posB) { + if (!posA || !posB) { return; } else { constantPatternPositions = std::tuple<std::array<uint16_t, 4>, std::array<uint16_t, 4>> { posB->tlbr(), posA->tlbr() }; @@ -431,17 +432,15 @@ PaintPropertyBinder<T, UniformValueType, PossiblyEvaluatedType, As...>::create(c } template <class Attr> -struct ZoomInterpolatedAttribute { - static auto name() { return Attr::name(); } +struct ZoomInterpolatedAttribute : public Attr { using Type = ZoomInterpolatedAttributeType<typename Attr::Type>; }; template <class Attr> struct InterpolationUniform { using Value = float; - static auto name() { - static const std::string name = Attr::name() + std::string("_t"); - return name.c_str(); + static constexpr auto name() { + return concat_literals<&Attr::name, &string_literal<'_', 't'>::value>::value(); } }; @@ -546,29 +545,6 @@ public: return result; } - template <class> - struct UniformDefines; - - template <class... Us> - struct UniformDefines<TypeList<Us...>> { - static void appendDefines(std::vector<std::string>& defines) { - util::ignore({ - (defines.push_back(std::string("#define HAS_UNIFORM_") + Us::name()), 0)... - }); - } - }; - - template <class EvaluatedProperties> - static std::vector<std::string> defines(const EvaluatedProperties& currentProperties) { - std::vector<std::string> result; - util::ignore({ - (currentProperties.template get<Ps>().isConstant() - ? UniformDefines<typename Ps::UniformList>::appendDefines(result) - : (void) 0, 0)... - }); - return result; - } - private: Binders binders; }; diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp index 32236d0f24..24a45b9146 100644 --- a/src/mbgl/renderer/render_layer.cpp +++ b/src/mbgl/renderer/render_layer.cpp @@ -3,7 +3,7 @@ #include <mbgl/renderer/render_tile.hpp> #include <mbgl/style/types.hpp> #include <mbgl/tile/tile.hpp> -#include <mbgl/gl/context.hpp> +#include <mbgl/gfx/context.hpp> #include <mbgl/util/logging.hpp> namespace mbgl { @@ -33,18 +33,9 @@ bool RenderLayer::needsRendering(float zoom) const { && baseImpl->maxZoom >= zoom; } -void RenderLayer::setRenderTiles(RenderTiles tiles, const TransformState& state) { - renderTiles = filterRenderTiles(std::move(tiles)); - sortRenderTiles(state); -} - -RenderLayer::RenderTiles RenderLayer::filterRenderTiles(RenderTiles tiles) const { +void RenderLayer::setRenderTiles(RenderTiles tiles, const TransformState&) { auto filterFn = [](auto& tile){ return !tile.tile.isRenderable() || tile.tile.holdForFade(); }; - return filterRenderTiles(std::move(tiles), filterFn); -} - -void RenderLayer::sortRenderTiles(const TransformState&) { - // no-op + renderTiles = filterRenderTiles(std::move(tiles), filterFn); } const RenderLayerSymbolInterface* RenderLayer::getSymbolInterface() const { diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index ec4c71b08c..98e151435a 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -63,7 +63,7 @@ public: const mat4&) const { return false; }; using RenderTiles = std::vector<std::reference_wrapper<RenderTile>>; - void setRenderTiles(RenderTiles, const TransformState&); + virtual void setRenderTiles(RenderTiles, const TransformState&); // Private implementation Immutable<style::Layer::Impl> baseImpl; @@ -84,9 +84,6 @@ protected: // in the console to inform the developer. void checkRenderability(const PaintParameters&, uint32_t activeBindingCount); - // Code specific to RenderTiles sorting / filtering - virtual RenderTiles filterRenderTiles(RenderTiles) const; - virtual void sortRenderTiles(const TransformState&); // For some layers, we want Buckets to cache their corresponding paint properties, so that outdated buckets (and // the cached paint properties) can be still in use while the tile is loading new buckets (which will // correpond to the current paint properties of the layer). diff --git a/src/mbgl/renderer/render_static_data.cpp b/src/mbgl/renderer/render_static_data.cpp index 16d0d64a33..24eed0326c 100644 --- a/src/mbgl/renderer/render_static_data.cpp +++ b/src/mbgl/renderer/render_static_data.cpp @@ -1,5 +1,5 @@ #include <mbgl/renderer/render_static_data.hpp> -#include <mbgl/gl/context.hpp> +#include <mbgl/gfx/context.hpp> #include <mbgl/programs/program_parameters.hpp> namespace mbgl { @@ -48,7 +48,7 @@ static gfx::VertexVector<ExtrusionTextureLayoutVertex> extrusionTextureVertices( return result; } -RenderStaticData::RenderStaticData(gl::Context& context, float pixelRatio, const optional<std::string>& programCacheDir) +RenderStaticData::RenderStaticData(gfx::Context& context, float pixelRatio, const optional<std::string>& programCacheDir) : tileVertexBuffer(context.createVertexBuffer(tileVertices())), rasterVertexBuffer(context.createVertexBuffer(rasterVertices())), extrusionTextureVertexBuffer(context.createVertexBuffer(extrusionTextureVertices())), diff --git a/src/mbgl/renderer/render_static_data.hpp b/src/mbgl/renderer/render_static_data.hpp index b9b52b09ca..23f632bc12 100644 --- a/src/mbgl/renderer/render_static_data.hpp +++ b/src/mbgl/renderer/render_static_data.hpp @@ -12,10 +12,13 @@ #include <string> namespace mbgl { +namespace gfx { +class Context; +} // namespace gfx class RenderStaticData { public: - RenderStaticData(gl::Context&, float pixelRatio, const optional<std::string>& programCacheDir); + RenderStaticData(gfx::Context&, float pixelRatio, const optional<std::string>& programCacheDir); gfx::VertexBuffer<gfx::Vertex<PositionOnlyLayoutAttributes>> tileVertexBuffer; gfx::VertexBuffer<RasterLayoutVertex> rasterVertexBuffer; diff --git a/src/mbgl/renderer/render_tile.cpp b/src/mbgl/renderer/render_tile.cpp index 24826bfd78..745a577683 100644 --- a/src/mbgl/renderer/render_tile.cpp +++ b/src/mbgl/renderer/render_tile.cpp @@ -4,7 +4,7 @@ #include <mbgl/renderer/render_static_data.hpp> #include <mbgl/programs/programs.hpp> #include <mbgl/map/transform_state.hpp> -#include <mbgl/gl/context.hpp> +#include <mbgl/gfx/cull_face_mode.hpp> #include <mbgl/tile/tile.hpp> #include <mbgl/util/math.hpp> @@ -105,8 +105,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { tile.debugBucket->segments, program.computeAllUniformValues( DebugProgram::LayoutUniformValues { - uniforms::u_matrix::Value( matrix ), - uniforms::u_color::Value( Color::white() ) + uniforms::matrix::Value( matrix ), + uniforms::color::Value( Color::white() ) }, paintAttributeData, properties, @@ -128,8 +128,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { tile.debugBucket->segments, program.computeAllUniformValues( DebugProgram::LayoutUniformValues { - uniforms::u_matrix::Value( matrix ), - uniforms::u_color::Value( Color::black() ) + uniforms::matrix::Value( matrix ), + uniforms::color::Value( Color::black() ) }, paintAttributeData, properties, @@ -153,8 +153,8 @@ void RenderTile::finishRender(PaintParameters& parameters) { parameters.staticData.tileBorderSegments, program.computeAllUniformValues( DebugProgram::LayoutUniformValues { - uniforms::u_matrix::Value( matrix ), - uniforms::u_color::Value( Color::red() ) + uniforms::matrix::Value( matrix ), + uniforms::color::Value( Color::red() ) }, paintAttributeData, properties, diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp index fbd9049207..4da7b78374 100644 --- a/src/mbgl/renderer/renderer.cpp +++ b/src/mbgl/renderer/renderer.cpp @@ -34,6 +34,10 @@ void Renderer::render(const UpdateParameters& updateParameters) { impl->render(updateParameters); } +void Renderer::flush() { + impl->flush(); +} + std::vector<Feature> Renderer::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options) const { return impl->queryRenderedFeatures(geometry, options); } diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 471536cf40..7144a2dcee 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -16,6 +16,7 @@ #include <mbgl/renderer/query.hpp> #include <mbgl/renderer/backend_scope.hpp> #include <mbgl/renderer/image_manager.hpp> +#include <mbgl/gl/context.hpp> #include <mbgl/gl/debugging.hpp> #include <mbgl/geometry/line_atlas.hpp> #include <mbgl/style/source_impl.hpp> @@ -82,6 +83,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { if (!imageManager) { imageManager = std::make_unique<ImageManager>(); + imageManager->setObserver(this); } if (updateParameters.mode != MapMode::Continuous) { @@ -142,6 +144,9 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { const ImageDifference imageDiff = diffImages(imageImpls, updateParameters.images); imageImpls = updateParameters.images; + // Only trigger tile reparse for changed images. Changed images only need a relayout when they have a different size. + bool hasImageDiff = !imageDiff.removed.empty(); + // Remove removed images from sprite atlas. for (const auto& entry : imageDiff.removed) { imageManager->removeImage(entry.first); @@ -154,9 +159,10 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { // Update changed images. for (const auto& entry : imageDiff.changed) { - imageManager->updateImage(entry.second.after); + hasImageDiff = imageManager->updateImage(entry.second.after) || hasImageDiff; } + imageManager->notifyIfMissingImageAdded(); imageManager->setLoaded(updateParameters.spriteLoaded); @@ -214,8 +220,6 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { renderSources.emplace(entry.first, std::move(renderSource)); } - const bool hasImageDiff = !(imageDiff.added.empty() && imageDiff.removed.empty() && imageDiff.changed.empty()); - // Update all sources. for (const auto& source : *sourceImpls) { std::vector<Immutable<Layer::Impl>> filteredLayers; @@ -262,7 +266,8 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { renderLight.getEvaluated(), *staticData, *imageManager, - *lineAtlas + *lineAtlas, + placement->getVariableOffsets() }; bool loaded = updateParameters.styleLoaded && isLoaded(); @@ -278,8 +283,11 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { backend.updateAssumedState(); + // TODO: remove cast + gl::Context& glContext = reinterpret_cast<gl::Context&>(parameters.context); + if (parameters.contextMode == GLContextMode::Shared) { - parameters.context.setDirtyState(); + glContext.setDirtyState(); } Color backgroundColor; @@ -292,6 +300,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { }; std::vector<RenderItem> order; + std::vector<const RenderLayerSymbolInterface*> renderItemsWithSymbols; for (auto& layerImpl : *layerImpls) { RenderLayer* layer = getRenderLayer(layerImpl->id); @@ -326,6 +335,10 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { layer->setRenderTiles(source->getRenderTiles(), parameters.state); order.emplace_back(*layer, source); + + if (const RenderLayerSymbolInterface* symbolLayer = layer->getSymbolInterface()) { + renderItemsWithSymbols.push_back(symbolLayer); + } } { @@ -334,32 +347,28 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { crossTileSymbolIndex.reset(); } - std::vector<RenderItem> renderItemsWithSymbols; - std::copy_if(order.rbegin(), order.rend(), std::back_inserter(renderItemsWithSymbols), - [](const auto& item) { return item.layer.getSymbolInterface() != nullptr; }); - bool symbolBucketsChanged = false; const bool placementChanged = !placement->stillRecent(parameters.timePoint); - std::unique_ptr<Placement> newPlacement; std::set<std::string> usedSymbolLayers; if (placementChanged) { - newPlacement = std::make_unique<Placement>(parameters.state, parameters.mapMode, updateParameters.transitionOptions, updateParameters.crossSourceCollisions); + placement = std::make_unique<Placement>(parameters.state, parameters.mapMode, updateParameters.transitionOptions, updateParameters.crossSourceCollisions, std::move(placement)); } - for (const auto& item : renderItemsWithSymbols) { - if (crossTileSymbolIndex.addLayer(*item.layer.getSymbolInterface(), parameters.state.getLatLng().longitude())) symbolBucketsChanged = true; + for (auto it = renderItemsWithSymbols.rbegin(); it != renderItemsWithSymbols.rend(); ++it) { + const RenderLayerSymbolInterface *symbolLayer = *it; + if (crossTileSymbolIndex.addLayer(*symbolLayer, parameters.state.getLatLng().longitude())) symbolBucketsChanged = true; - if (newPlacement) { - usedSymbolLayers.insert(item.layer.getID()); - newPlacement->placeLayer(*item.layer.getSymbolInterface(), parameters.projMatrix, parameters.debugOptions & MapDebugOptions::Collision); + if (placementChanged) { + usedSymbolLayers.insert(symbolLayer->layerID()); + placement->placeLayer(*symbolLayer, parameters.projMatrix, parameters.debugOptions & MapDebugOptions::Collision); } } - if (newPlacement) { - newPlacement->commit(*placement, parameters.timePoint); + if (placementChanged) { + placement->commit(parameters.timePoint); crossTileSymbolIndex.pruneUnusedLayers(usedSymbolLayers); - placement = std::move(newPlacement); + parameters.variableOffsets = placement->getVariableOffsets(); updateFadingTiles(); } else { placement->setStale(); @@ -368,8 +377,9 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { parameters.symbolFadeChange = placement->symbolFadeChange(parameters.timePoint); if (placementChanged || symbolBucketsChanged) { - for (const auto& item : renderItemsWithSymbols) { - placement->updateLayerOpacities(*item.layer.getSymbolInterface()); + for (auto it = renderItemsWithSymbols.rbegin(); it != renderItemsWithSymbols.rend(); ++it) { + const RenderLayerSymbolInterface *symbolLayer = *it; + placement->updateLayerOpacities(*symbolLayer); } } } @@ -402,7 +412,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { if (!parameters.staticData.depthRenderbuffer || parameters.staticData.depthRenderbuffer->size != parameters.staticData.backendSize) { parameters.staticData.depthRenderbuffer = - parameters.context.createRenderbuffer<gl::RenderbufferType::DepthComponent>(parameters.staticData.backendSize); + glContext.createRenderbuffer<gl::RenderbufferType::DepthComponent>(parameters.staticData.backendSize); } parameters.staticData.depthRenderbuffer->shouldClear(true); @@ -425,11 +435,11 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { MBGL_DEBUG_GROUP(parameters.context, "clear"); parameters.backend.bind(); if (parameters.debugOptions & MapDebugOptions::Overdraw) { - parameters.context.clear(Color::black(), ClearDepth::Default, ClearStencil::Default); + glContext.clear(Color::black(), ClearDepth::Default, ClearStencil::Default); } else if (parameters.contextMode == GLContextMode::Shared) { - parameters.context.clear({}, ClearDepth::Default, ClearStencil::Default); + glContext.clear({}, ClearDepth::Default, ClearStencil::Default); } else { - parameters.context.clear(backgroundColor, ClearDepth::Default, ClearStencil::Default); + glContext.clear(backgroundColor, ClearDepth::Default, ClearStencil::Default); } } @@ -462,7 +472,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { parameters.staticData.tileTriangleSegments, program.computeAllUniformValues( ClippingMaskProgram::LayoutUniformValues { - uniforms::u_matrix::Value( parameters.matrixForTile(clipID.first) ), + uniforms::matrix::Value( parameters.matrixForTile(clipID.first) ), }, paintAttributeData, properties, @@ -482,17 +492,17 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { #if not MBGL_USE_GLES2 and not defined(NDEBUG) // Render tile clip boundaries, using stencil buffer to calculate fill color. if (parameters.debugOptions & MapDebugOptions::StencilClip) { - parameters.context.setStencilMode(gfx::StencilMode::disabled()); - parameters.context.setDepthMode(gfx::DepthMode::disabled()); - parameters.context.setColorMode(gfx::ColorMode::unblended()); - parameters.context.program = 0; + glContext.setStencilMode(gfx::StencilMode::disabled()); + glContext.setDepthMode(gfx::DepthMode::disabled()); + glContext.setColorMode(gfx::ColorMode::unblended()); + glContext.program = 0; // Reset the value in case someone else changed it, or it's dirty. - parameters.context.pixelTransferStencil = gl::value::PixelTransferStencil::Default; + glContext.pixelTransferStencil = gl::value::PixelTransferStencil::Default; // Read the stencil buffer - const auto viewport = parameters.context.viewport.getCurrentValue(); - auto image = parameters.context.readFramebuffer<AlphaImage, gfx::TexturePixelType::Stencil>(viewport.size, false); + const auto viewport = glContext.viewport.getCurrentValue(); + auto image = glContext.readFramebuffer<AlphaImage, gfx::TexturePixelType::Stencil>(viewport.size, false); // Scale the Stencil buffer to cover the entire color space. auto it = image.data.get(); @@ -502,9 +512,9 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { *it *= factor; } - parameters.context.pixelZoom = { 1, 1 }; - parameters.context.rasterPos = { -1, -1, 0, 1 }; - parameters.context.drawPixels(image); + glContext.pixelZoom = { 1, 1 }; + glContext.rasterPos = { -1, -1, 0, 1 }; + glContext.drawPixels(image); return; } @@ -565,39 +575,26 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { #if not MBGL_USE_GLES2 and not defined(NDEBUG) // Render the depth buffer. if (parameters.debugOptions & MapDebugOptions::DepthBuffer) { - parameters.context.setStencilMode(gfx::StencilMode::disabled()); - parameters.context.setDepthMode(gfx::DepthMode::disabled()); - parameters.context.setColorMode(gfx::ColorMode::unblended()); - parameters.context.program = 0; + glContext.setStencilMode(gfx::StencilMode::disabled()); + glContext.setDepthMode(gfx::DepthMode::disabled()); + glContext.setColorMode(gfx::ColorMode::unblended()); + glContext.program = 0; // Scales the values in the depth buffer so that they cover the entire grayscale range. This // makes it easier to spot tiny differences. const float base = 1.0f / (1.0f - parameters.depthRangeSize); - parameters.context.pixelTransferDepth = { base, 1.0f - base }; + glContext.pixelTransferDepth = { base, 1.0f - base }; // Read the stencil buffer - auto viewport = parameters.context.viewport.getCurrentValue(); - auto image = parameters.context.readFramebuffer<AlphaImage, gfx::TexturePixelType::Depth>(viewport.size, false); + auto viewport = glContext.viewport.getCurrentValue(); + auto image = glContext.readFramebuffer<AlphaImage, gfx::TexturePixelType::Depth>(viewport.size, false); - parameters.context.pixelZoom = { 1, 1 }; - parameters.context.rasterPos = { -1, -1, 0, 1 }; - parameters.context.drawPixels(image); + glContext.pixelZoom = { 1, 1 }; + glContext.rasterPos = { -1, -1, 0, 1 }; + glContext.drawPixels(image); } #endif - // TODO: Find a better way to unbind VAOs after we're done with them without introducing - // unnecessary bind(0)/bind(N) sequences. - { - MBGL_DEBUG_GROUP(parameters.context, "cleanup"); - - parameters.context.activeTextureUnit = 1; - parameters.context.texture[1] = 0; - parameters.context.activeTextureUnit = 0; - parameters.context.texture[0] = 0; - - parameters.context.bindVertexArray = 0; - } - observer->onDidFinishRenderingFrame( loaded ? RendererObserver::RenderMode::Full : RendererObserver::RenderMode::Partial, updateParameters.mode == MapMode::Continuous && hasTransitions(parameters.timePoint) @@ -614,6 +611,12 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { parameters.context.performCleanup(); } +void Renderer::Impl::flush() { + assert(BackendScope::exists()); + + backend.getContext().flush(); +} + std::vector<Feature> Renderer::Impl::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options) const { std::vector<const RenderLayer*> layers; if (options.layerIDs) { @@ -837,4 +840,8 @@ void Renderer::Impl::onTileChanged(RenderSource&, const OverscaledTileID&) { observer->onInvalidate(); } +void Renderer::Impl::onStyleImageMissing(const std::string& id, std::function<void()> done) { + observer->onStyleImageMissing(id, std::move(done)); +} + } // namespace mbgl diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp index 05bf2e9b2b..624b4c273c 100644 --- a/src/mbgl/renderer/renderer_impl.hpp +++ b/src/mbgl/renderer/renderer_impl.hpp @@ -11,6 +11,7 @@ #include <mbgl/map/zoom_history.hpp> #include <mbgl/text/cross_tile_symbol_index.hpp> #include <mbgl/text/glyph_manager_observer.hpp> +#include <mbgl/renderer/image_manager_observer.hpp> #include <mbgl/text/placement.hpp> #include <memory> @@ -34,6 +35,7 @@ class LineAtlas; class CrossTileSymbolIndex; class Renderer::Impl : public GlyphManagerObserver, + public ImageManagerObserver, public RenderSourceObserver{ public: Impl(RendererBackend&, float pixelRatio_, Scheduler&, GLContextMode, @@ -48,6 +50,8 @@ public: void render(const UpdateParameters&); + void flush(); + std::vector<Feature> queryRenderedFeatures(const ScreenLineString&, const RenderedQueryOptions&) const; std::vector<Feature> querySourceFeatures(const std::string& sourceID, const SourceQueryOptions&) const; std::vector<Feature> queryShapeAnnotations(const ScreenLineString&) const; @@ -84,6 +88,9 @@ private: void onTileChanged(RenderSource&, const OverscaledTileID&) override; void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) override; + // ImageManagerObserver implementation + void onStyleImageMissing(const std::string&, std::function<void()>) override; + void updateFadingTiles(); friend class Renderer; diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index 1b135a2838..dee3eab750 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -7,7 +7,7 @@ #include <mbgl/renderer/tile_parameters.hpp> #include <mbgl/renderer/render_static_data.hpp> #include <mbgl/programs/programs.hpp> -#include <mbgl/gl/context.hpp> +#include <mbgl/gfx/cull_face_mode.hpp> #include <mbgl/util/tile_coordinate.hpp> #include <mbgl/util/tile_cover.hpp> #include <mbgl/util/logging.hpp> @@ -73,8 +73,8 @@ void RenderImageSource::finishRender(PaintParameters& parameters) { parameters.staticData.tileBorderSegments, programInstance.computeAllUniformValues( DebugProgram::LayoutUniformValues { - uniforms::u_matrix::Value( matrix ), - uniforms::u_color::Value( Color::red() ) + uniforms::matrix::Value( matrix ), + uniforms::color::Value( Color::red() ) }, paintAttributeData, properties, diff --git a/src/mbgl/storage/asset_file_source.hpp b/src/mbgl/storage/asset_file_source.hpp index 5d98b4e69e..cc15dbb60b 100644 --- a/src/mbgl/storage/asset_file_source.hpp +++ b/src/mbgl/storage/asset_file_source.hpp @@ -10,7 +10,7 @@ template <typename T> class Thread; class AssetFileSource : public FileSource { public: - AssetFileSource(const std::string& assetRoot); + AssetFileSource(const std::string& assetPath); ~AssetFileSource() override; std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override; diff --git a/src/mbgl/storage/file_source.cpp b/src/mbgl/storage/file_source.cpp new file mode 100644 index 0000000000..5854682771 --- /dev/null +++ b/src/mbgl/storage/file_source.cpp @@ -0,0 +1,37 @@ +#include <mbgl/storage/file_source.hpp> +#include <mbgl/storage/resource_options.hpp> +#include <mbgl/util/string.hpp> + +#include <mutex> +#include <map> + +namespace mbgl { + +std::shared_ptr<FileSource> FileSource::getSharedFileSource(const ResourceOptions& options) { + static std::mutex mutex; + static std::map<std::string, std::weak_ptr<mbgl::FileSource>> fileSources; + + std::lock_guard<std::mutex> lock(mutex); + + // Purge entries no longer in use. + for (auto it = fileSources.begin(); it != fileSources.end();) { + it = it->second.expired() ? fileSources.erase(it) : ++it; + } + + const uint64_t context = reinterpret_cast<uint64_t>(options.platformContext()); + const std::string key = options.baseURL() + '|' + options.accessToken() + '|' + options.cachePath() + '|' + util::toString(context); + + std::shared_ptr<mbgl::FileSource> fileSource; + auto tuple = fileSources.find(key); + if (tuple != fileSources.end()) { + fileSource = tuple->second.lock(); + } + + if (!fileSource) { + fileSources[key] = fileSource = createPlatformFileSource(options); + } + + return fileSource; +} + +} // namespace mbgl diff --git a/src/mbgl/storage/resource_options.cpp b/src/mbgl/storage/resource_options.cpp new file mode 100644 index 0000000000..c56a22540b --- /dev/null +++ b/src/mbgl/storage/resource_options.cpp @@ -0,0 +1,80 @@ +#include <mbgl/storage/resource_options.hpp> +#include <mbgl/util/constants.hpp> + +namespace mbgl { + +class ResourceOptions::Impl { +public: + std::string accessToken; + std::string baseURL = mbgl::util::API_BASE_URL; + std::string cachePath = ":memory:"; + std::string assetPath = "."; + uint64_t maximumSize = mbgl::util::DEFAULT_MAX_CACHE_SIZE; + void* platformContext = nullptr; +}; + +// These requires the complete type of Impl. +ResourceOptions::ResourceOptions() : impl_(std::make_unique<Impl>()) {} +ResourceOptions::~ResourceOptions() = default; +ResourceOptions::ResourceOptions(ResourceOptions&&) noexcept = default; +ResourceOptions::ResourceOptions(const ResourceOptions& other) : impl_(std::make_unique<Impl>(*other.impl_)) {} + +ResourceOptions ResourceOptions::clone() const { + return ResourceOptions(*this); +} + +ResourceOptions& ResourceOptions::withAccessToken(std::string token) { + impl_->accessToken = std::move(token); + return *this; +} + +const std::string& ResourceOptions::accessToken() const { + return impl_->accessToken; +} + +ResourceOptions& ResourceOptions::withBaseURL(std::string url) { + impl_->baseURL = std::move(url); + return *this; +} + +const std::string& ResourceOptions::baseURL() const { + return impl_->baseURL; +} + +ResourceOptions& ResourceOptions::withCachePath(std::string path) { + impl_->cachePath = std::move(path); + return *this; +} + +const std::string& ResourceOptions::cachePath() const { + return impl_->cachePath; +} + +ResourceOptions& ResourceOptions::withAssetPath(std::string path) { + impl_->assetPath = std::move(path); + return *this; +} + +const std::string& ResourceOptions::assetPath() const { + return impl_->assetPath; +} + +ResourceOptions& ResourceOptions::withMaximumCacheSize(uint64_t size) { + impl_->maximumSize = size; + return *this; +} + +uint64_t ResourceOptions::maximumCacheSize() const { + return impl_->maximumSize; +} + +ResourceOptions& ResourceOptions::withPlatformContext(void* context) { + impl_->platformContext = context; + return *this; +} + +void* ResourceOptions::platformContext() const { + return impl_->platformContext; +} + +} // namespace mbgl diff --git a/src/mbgl/style/conversion/constant.cpp b/src/mbgl/style/conversion/constant.cpp index bdc6371722..0fcaab433b 100644 --- a/src/mbgl/style/conversion/constant.cpp +++ b/src/mbgl/style/conversion/constant.cpp @@ -49,6 +49,27 @@ optional<T> Converter<T, typename std::enable_if_t<std::is_enum<T>::value>>::ope return *result; } +template <class T> +auto Converter<std::vector<T>, typename std::enable_if_t<std::is_enum<T>::value>>::operator()(const Convertible& value, Error& error) const -> optional<std::vector<T>> { + if (!isArray(value)) { + error.message = "value must be an array"; + return nullopt; + } + + std::vector<T> result; + result.reserve(arrayLength(value)); + + for (std::size_t i = 0; i < arrayLength(value); ++i) { + optional<T> enumItem = Converter<T>{}(arrayMember(value, i), error); + if (!enumItem) { + return nullopt; + } + result.push_back(*enumItem); + } + + return result; +} + template optional<AlignmentType> Converter<AlignmentType>::operator()(const Convertible&, Error&) const; template optional<CirclePitchScaleType> Converter<CirclePitchScaleType>::operator()(const Convertible&, Error&) const; template optional<HillshadeIlluminationAnchorType> Converter<HillshadeIlluminationAnchorType>::operator()(const Convertible&, Error&) const; @@ -64,6 +85,7 @@ template optional<TextJustifyType> Converter<TextJustifyType>::operator()(const template optional<TextTransformType> Converter<TextTransformType>::operator()(const Convertible&, Error&) const; template optional<TranslateAnchorType> Converter<TranslateAnchorType>::operator()(const Convertible&, Error&) const; template optional<VisibilityType> Converter<VisibilityType>::operator()(const Convertible&, Error&) const; +template optional<std::vector<TextVariableAnchorType>> Converter<std::vector<TextVariableAnchorType>>::operator()(const Convertible&, Error&) const; optional<Color> Converter<Color>::operator()(const Convertible& value, Error& error) const { optional<std::string> string = toString(value); diff --git a/src/mbgl/style/conversion/function.cpp b/src/mbgl/style/conversion/function.cpp index 79ad2fc7d8..df4decc73e 100644 --- a/src/mbgl/style/conversion/function.cpp +++ b/src/mbgl/style/conversion/function.cpp @@ -136,6 +136,8 @@ template optional<PropertyExpression<std::vector<std::string>>> convertFunctionToExpression<std::vector<std::string>>(const Convertible&, Error&, bool); template optional<PropertyExpression<SymbolAnchorType>> convertFunctionToExpression<SymbolAnchorType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<std::vector<TextVariableAnchorType>>> + convertFunctionToExpression<std::vector<TextVariableAnchorType>>(const Convertible&, Error&, bool); template optional<PropertyExpression<SymbolPlacementType>> convertFunctionToExpression<SymbolPlacementType>(const Convertible&, Error&, bool); template optional<PropertyExpression<SymbolZOrderType>> diff --git a/src/mbgl/style/conversion/property_value.cpp b/src/mbgl/style/conversion/property_value.cpp index ff038908b6..6e1d747324 100644 --- a/src/mbgl/style/conversion/property_value.cpp +++ b/src/mbgl/style/conversion/property_value.cpp @@ -73,6 +73,7 @@ template optional<PropertyValue<LineJoinType>> Converter<PropertyValue<LineJoinT template optional<PropertyValue<Position>> Converter<PropertyValue<Position>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional<PropertyValue<RasterResamplingType>> Converter<PropertyValue<RasterResamplingType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional<PropertyValue<SymbolAnchorType>> Converter<PropertyValue<SymbolAnchorType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<std::vector<TextVariableAnchorType>>> Converter<PropertyValue<std::vector<TextVariableAnchorType>>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional<PropertyValue<SymbolPlacementType>> Converter<PropertyValue<SymbolPlacementType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional<PropertyValue<SymbolZOrderType>> Converter<PropertyValue<SymbolZOrderType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; template optional<PropertyValue<TextJustifyType>> Converter<PropertyValue<TextJustifyType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; diff --git a/src/mbgl/style/expression/value.cpp b/src/mbgl/style/expression/value.cpp index 436ed83ecd..e826a8a3cc 100644 --- a/src/mbgl/style/expression/value.cpp +++ b/src/mbgl/style/expression/value.cpp @@ -166,6 +166,11 @@ mbgl::Value ValueConverter<mbgl::Value>::fromExpressionValue(const Value& value) } options.emplace("text-font", std::vector<mbgl::Value>{ std::string("literal"), fontStack }); } + + if (section.textColor) { + options.emplace("text-color", fromExpressionValue(*section.textColor)); + } + serialized.push_back(options); } return serialized; @@ -324,6 +329,9 @@ template struct ValueConverter<std::vector<float>>; template type::Type valueTypeToExpressionType<std::vector<std::string>>(); template struct ValueConverter<std::vector<std::string>>; +template type::Type valueTypeToExpressionType<std::vector<TextVariableAnchorType>>(); +template struct ValueConverter<std::vector<TextVariableAnchorType>>; + template type::Type valueTypeToExpressionType<AlignmentType>(); template struct ValueConverter<AlignmentType>; diff --git a/src/mbgl/style/image_impl.hpp b/src/mbgl/style/image_impl.hpp index 54b5e6487b..b2decbf781 100644 --- a/src/mbgl/style/image_impl.hpp +++ b/src/mbgl/style/image_impl.hpp @@ -34,5 +34,6 @@ enum class ImageType : bool { using ImageMap = std::unordered_map<std::string, Immutable<style::Image::Impl>>; using ImageDependencies = std::unordered_map<std::string, ImageType>; using ImageRequestPair = std::pair<ImageDependencies, uint64_t>; +using ImageVersionMap = std::unordered_map<std::string, uint32_t>; } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp index bc0c961e75..57caba9e3a 100644 --- a/src/mbgl/style/layers/circle_layer_properties.hpp +++ b/src/mbgl/style/layers/circle_layer_properties.hpp @@ -12,19 +12,19 @@ namespace mbgl { namespace style { -struct CircleRadius : DataDrivenPaintProperty<float, attributes::a_radius, uniforms::u_radius> { +struct CircleRadius : DataDrivenPaintProperty<float, attributes::radius, uniforms::radius> { static float defaultValue() { return 5; } }; -struct CircleColor : DataDrivenPaintProperty<Color, attributes::a_color, uniforms::u_color> { +struct CircleColor : DataDrivenPaintProperty<Color, attributes::color, uniforms::color> { static Color defaultValue() { return Color::black(); } }; -struct CircleBlur : DataDrivenPaintProperty<float, attributes::a_blur, uniforms::u_blur> { +struct CircleBlur : DataDrivenPaintProperty<float, attributes::blur, uniforms::blur> { static float defaultValue() { return 0; } }; -struct CircleOpacity : DataDrivenPaintProperty<float, attributes::a_opacity, uniforms::u_opacity> { +struct CircleOpacity : DataDrivenPaintProperty<float, attributes::opacity, uniforms::opacity> { static float defaultValue() { return 1; } }; @@ -44,15 +44,15 @@ struct CirclePitchAlignment : PaintProperty<AlignmentType> { static AlignmentType defaultValue() { return AlignmentType::Viewport; } }; -struct CircleStrokeWidth : DataDrivenPaintProperty<float, attributes::a_stroke_width, uniforms::u_stroke_width> { +struct CircleStrokeWidth : DataDrivenPaintProperty<float, attributes::stroke_width, uniforms::stroke_width> { static float defaultValue() { return 0; } }; -struct CircleStrokeColor : DataDrivenPaintProperty<Color, attributes::a_stroke_color, uniforms::u_stroke_color> { +struct CircleStrokeColor : DataDrivenPaintProperty<Color, attributes::stroke_color, uniforms::stroke_color> { static Color defaultValue() { return Color::black(); } }; -struct CircleStrokeOpacity : DataDrivenPaintProperty<float, attributes::a_stroke_opacity, uniforms::u_stroke_opacity> { +struct CircleStrokeOpacity : DataDrivenPaintProperty<float, attributes::stroke_opacity, uniforms::stroke_opacity> { static float defaultValue() { return 1; } }; diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp index 20cba699fe..a7799eee22 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp @@ -16,7 +16,7 @@ struct FillExtrusionOpacity : PaintProperty<float> { static float defaultValue() { return 1; } }; -struct FillExtrusionColor : DataDrivenPaintProperty<Color, attributes::a_color, uniforms::u_color> { +struct FillExtrusionColor : DataDrivenPaintProperty<Color, attributes::color, uniforms::color> { static Color defaultValue() { return Color::black(); } }; @@ -28,15 +28,15 @@ struct FillExtrusionTranslateAnchor : PaintProperty<TranslateAnchorType> { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -struct FillExtrusionPattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::a_pattern_to, uniforms::u_pattern_to, attributes::a_pattern_from, uniforms::u_pattern_from> { +struct FillExtrusionPattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::pattern_to, uniforms::pattern_to, attributes::pattern_from, uniforms::pattern_from> { static std::string defaultValue() { return ""; } }; -struct FillExtrusionHeight : DataDrivenPaintProperty<float, attributes::a_height, uniforms::u_height> { +struct FillExtrusionHeight : DataDrivenPaintProperty<float, attributes::height, uniforms::height> { static float defaultValue() { return 0; } }; -struct FillExtrusionBase : DataDrivenPaintProperty<float, attributes::a_base, uniforms::u_base> { +struct FillExtrusionBase : DataDrivenPaintProperty<float, attributes::base, uniforms::base> { static float defaultValue() { return 0; } }; diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp index a20089ff2e..942733f2e1 100644 --- a/src/mbgl/style/layers/fill_layer_properties.hpp +++ b/src/mbgl/style/layers/fill_layer_properties.hpp @@ -16,15 +16,15 @@ struct FillAntialias : PaintProperty<bool> { static bool defaultValue() { return true; } }; -struct FillOpacity : DataDrivenPaintProperty<float, attributes::a_opacity, uniforms::u_opacity> { +struct FillOpacity : DataDrivenPaintProperty<float, attributes::opacity, uniforms::opacity> { static float defaultValue() { return 1; } }; -struct FillColor : DataDrivenPaintProperty<Color, attributes::a_color, uniforms::u_color> { +struct FillColor : DataDrivenPaintProperty<Color, attributes::color, uniforms::color> { static Color defaultValue() { return Color::black(); } }; -struct FillOutlineColor : DataDrivenPaintProperty<Color, attributes::a_outline_color, uniforms::u_outline_color> { +struct FillOutlineColor : DataDrivenPaintProperty<Color, attributes::outline_color, uniforms::outline_color> { static Color defaultValue() { return {}; } }; @@ -36,7 +36,7 @@ struct FillTranslateAnchor : PaintProperty<TranslateAnchorType> { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -struct FillPattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::a_pattern_to, uniforms::u_pattern_to, attributes::a_pattern_from, uniforms::u_pattern_from> { +struct FillPattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::pattern_to, uniforms::pattern_to, attributes::pattern_from, uniforms::pattern_from> { static std::string defaultValue() { return ""; } }; diff --git a/src/mbgl/style/layers/heatmap_layer_properties.hpp b/src/mbgl/style/layers/heatmap_layer_properties.hpp index 4d49a52c72..ce00217b2e 100644 --- a/src/mbgl/style/layers/heatmap_layer_properties.hpp +++ b/src/mbgl/style/layers/heatmap_layer_properties.hpp @@ -12,11 +12,11 @@ namespace mbgl { namespace style { -struct HeatmapRadius : DataDrivenPaintProperty<float, attributes::a_radius, uniforms::u_radius> { +struct HeatmapRadius : DataDrivenPaintProperty<float, attributes::radius, uniforms::radius> { static float defaultValue() { return 30; } }; -struct HeatmapWeight : DataDrivenPaintProperty<float, attributes::a_weight, uniforms::u_weight> { +struct HeatmapWeight : DataDrivenPaintProperty<float, attributes::weight, uniforms::weight> { static float defaultValue() { return 1; } }; diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs index fcae615fe0..201189c849 100644 --- a/src/mbgl/style/layers/layer.cpp.ejs +++ b/src/mbgl/style/layers/layer.cpp.ejs @@ -153,6 +153,9 @@ void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyV return; auto impl_ = mutableImpl(); impl_->paint.template get<<%- camelize(property.name) %>>().value = value; +<% if (property.name === 'line-width') { -%> + impl_->paint.template get<LineFloorWidth>().value = value; +<% } -%> baseImpl = std::move(impl_); observer->onLayerChanged(*this); } diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs index 89dffdcd42..de647fbc07 100644 --- a/src/mbgl/style/layers/layer_properties.hpp.ejs +++ b/src/mbgl/style/layers/layer_properties.hpp.ejs @@ -37,6 +37,13 @@ struct <%- camelize(property.name) %> : <%- paintPropertyType(property, type) %> template<typename T> static bool hasOverride(const T& t) { return !!t.<%- camelizeWithLeadingLowercase(property.name) %>; }; <% } -%> }; +<% if (property.name === 'line-width') { -%> + +struct LineFloorWidth : DataDrivenPaintProperty<float, attributes::floorwidth, uniforms::floorwidth> { + using EvaluatorType = DataDrivenPropertyEvaluator<float, true>; + static float defaultValue() { return 1.0f; } +}; +<% } -%> <% } -%> <% } -%> @@ -52,6 +59,9 @@ class <%- camelize(type) %>LayoutProperties : public Properties< class <%- camelize(type) %>PaintProperties : public Properties< <% for (const property of paintProperties.slice(0, -1)) { -%> <%- camelize(property.name) %>, +<% if (property.name === 'line-width') { -%> + LineFloorWidth, +<% } -%> <% } -%> <%- camelize(paintProperties.slice(-1)[0].name) %> > {}; diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index 643c294edf..0a20762697 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -248,6 +248,7 @@ void LineLayer::setLineWidth(PropertyValue<float> value) { return; auto impl_ = mutableImpl(); impl_->paint.template get<LineWidth>().value = value; + impl_->paint.template get<LineFloorWidth>().value = value; baseImpl = std::move(impl_); observer->onLayerChanged(*this); } diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index bab6e77ce5..33d7eddbe8 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -32,11 +32,11 @@ struct LineRoundLimit : LayoutProperty<float> { static float defaultValue() { return 1; } }; -struct LineOpacity : DataDrivenPaintProperty<float, attributes::a_opacity, uniforms::u_opacity> { +struct LineOpacity : DataDrivenPaintProperty<float, attributes::opacity, uniforms::opacity> { static float defaultValue() { return 1; } }; -struct LineColor : DataDrivenPaintProperty<Color, attributes::a_color, uniforms::u_color> { +struct LineColor : DataDrivenPaintProperty<Color, attributes::color, uniforms::color> { static Color defaultValue() { return Color::black(); } }; @@ -48,19 +48,24 @@ struct LineTranslateAnchor : PaintProperty<TranslateAnchorType> { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -struct LineWidth : DataDrivenPaintProperty<float, attributes::a_width, uniforms::u_width> { +struct LineWidth : DataDrivenPaintProperty<float, attributes::width, uniforms::width> { static float defaultValue() { return 1; } }; -struct LineGapWidth : DataDrivenPaintProperty<float, attributes::a_gapwidth, uniforms::u_gapwidth> { +struct LineFloorWidth : DataDrivenPaintProperty<float, attributes::floorwidth, uniforms::floorwidth> { + using EvaluatorType = DataDrivenPropertyEvaluator<float, true>; + static float defaultValue() { return 1.0f; } +}; + +struct LineGapWidth : DataDrivenPaintProperty<float, attributes::gapwidth, uniforms::gapwidth> { static float defaultValue() { return 0; } }; -struct LineOffset : DataDrivenPaintProperty<float, attributes::a_offset, uniforms::u_offset> { +struct LineOffset : DataDrivenPaintProperty<float, attributes::offset, uniforms::offset> { static float defaultValue() { return 0; } }; -struct LineBlur : DataDrivenPaintProperty<float, attributes::a_blur, uniforms::u_blur> { +struct LineBlur : DataDrivenPaintProperty<float, attributes::blur, uniforms::blur> { static float defaultValue() { return 0; } }; @@ -68,7 +73,7 @@ struct LineDasharray : CrossFadedPaintProperty<std::vector<float>> { static std::vector<float> defaultValue() { return { }; } }; -struct LinePattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::a_pattern_to, uniforms::u_pattern_to, attributes::a_pattern_from, uniforms::u_pattern_from> { +struct LinePattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::pattern_to, uniforms::pattern_to, attributes::pattern_from, uniforms::pattern_from> { static std::string defaultValue() { return ""; } }; @@ -88,6 +93,7 @@ class LinePaintProperties : public Properties< LineTranslate, LineTranslateAnchor, LineWidth, + LineFloorWidth, LineGapWidth, LineOffset, LineBlur, diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index 75ed881058..1c56888f73 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -492,6 +492,38 @@ void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) { baseImpl = std::move(impl_); observer->onLayerChanged(*this); } +PropertyValue<float> SymbolLayer::getDefaultTextRadialOffset() { + return TextRadialOffset::defaultValue(); +} + +PropertyValue<float> SymbolLayer::getTextRadialOffset() const { + return impl().layout.get<TextRadialOffset>(); +} + +void SymbolLayer::setTextRadialOffset(PropertyValue<float> value) { + if (value == getTextRadialOffset()) + return; + auto impl_ = mutableImpl(); + impl_->layout.get<TextRadialOffset>() = value; + baseImpl = std::move(impl_); + observer->onLayerChanged(*this); +} +PropertyValue<std::vector<TextVariableAnchorType>> SymbolLayer::getDefaultTextVariableAnchor() { + return TextVariableAnchor::defaultValue(); +} + +PropertyValue<std::vector<TextVariableAnchorType>> SymbolLayer::getTextVariableAnchor() const { + return impl().layout.get<TextVariableAnchor>(); +} + +void SymbolLayer::setTextVariableAnchor(PropertyValue<std::vector<TextVariableAnchorType>> value) { + if (value == getTextVariableAnchor()) + return; + auto impl_ = mutableImpl(); + impl_->layout.get<TextVariableAnchor>() = value; + baseImpl = std::move(impl_); + observer->onLayerChanged(*this); +} PropertyValue<SymbolAnchorType> SymbolLayer::getDefaultTextAnchor() { return TextAnchor::defaultValue(); } @@ -1325,6 +1357,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co TextLineHeight, TextLetterSpacing, TextJustify, + TextRadialOffset, + TextVariableAnchor, TextAnchor, TextMaxAngle, TextRotate, @@ -1364,6 +1398,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co { "text-line-height", static_cast<uint8_t>(Property::TextLineHeight) }, { "text-letter-spacing", static_cast<uint8_t>(Property::TextLetterSpacing) }, { "text-justify", static_cast<uint8_t>(Property::TextJustify) }, + { "text-radial-offset", static_cast<uint8_t>(Property::TextRadialOffset) }, + { "text-variable-anchor", static_cast<uint8_t>(Property::TextVariableAnchor) }, { "text-anchor", static_cast<uint8_t>(Property::TextAnchor) }, { "text-max-angle", static_cast<uint8_t>(Property::TextMaxAngle) }, { "text-rotate", static_cast<uint8_t>(Property::TextRotate) }, @@ -1525,7 +1561,7 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co } - if (property == Property::IconSize || property == Property::IconRotate || property == Property::TextSize || property == Property::TextMaxWidth || property == Property::TextLetterSpacing || property == Property::TextRotate) { + if (property == Property::IconSize || property == Property::IconRotate || property == Property::TextSize || property == Property::TextMaxWidth || property == Property::TextLetterSpacing || property == Property::TextRadialOffset || property == Property::TextRotate) { Error error; optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, true, false); if (!typedValue) { @@ -1557,6 +1593,11 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co return nullopt; } + if (property == Property::TextRadialOffset) { + setTextRadialOffset(*typedValue); + return nullopt; + } + if (property == Property::TextRotate) { setTextRotate(*typedValue); return nullopt; @@ -1674,6 +1715,18 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co } + if (property == Property::TextVariableAnchor) { + Error error; + optional<PropertyValue<std::vector<TextVariableAnchorType>>> typedValue = convert<PropertyValue<std::vector<TextVariableAnchorType>>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setTextVariableAnchor(*typedValue); + return nullopt; + + } + if (property == Property::TextTransform) { Error error; optional<PropertyValue<TextTransformType>> typedValue = convert<PropertyValue<TextTransformType>>(value, error, true, false); diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp index f937fccaa8..9b63e0e8d6 100644 --- a/src/mbgl/style/layers/symbol_layer_impl.hpp +++ b/src/mbgl/style/layers/symbol_layer_impl.hpp @@ -3,9 +3,11 @@ #include <mbgl/style/layer_impl.hpp> #include <mbgl/style/layers/symbol_layer.hpp> #include <mbgl/style/layers/symbol_layer_properties.hpp> +#include <mbgl/style/expression/literal.hpp> #include <mbgl/style/expression/format_expression.hpp> #include <mbgl/style/expression/formatted.hpp> #include <mbgl/style/expression/format_section_override.hpp> +#include <mbgl/style/expression/value.hpp> namespace mbgl { namespace style { @@ -56,25 +58,57 @@ struct FormatSectionOverrides<TypeList<PaintProperty...>> { template<typename Property, typename FormattedProperty> static bool hasOverride(const FormattedProperty& formatted) { + + const auto checkLiteral = [] (const TextField::Type& literal) { + for (const auto& section : literal.sections) { + if (Property::hasOverride(section)) { + return true; + } + } + return false; + }; + return formatted.match( - [] (const TextField::Type& t) { - for (const auto& section : t.sections) { - if (Property::hasOverride(section)) { - return true; - } - } - return false; + [&checkLiteral] (const TextField::Type& literal) { + return checkLiteral(literal); }, - [] (const PropertyExpression<TextField::Type>& t) { - if (t.getExpression().getKind() == expression::Kind::FormatExpression) { - const auto* e = static_cast<const expression::FormatExpression*>(&t.getExpression()); - for (const auto& section : e->getSections()) { - if (Property::hasOverride(section)) { - return true; + [&checkLiteral] (const PropertyExpression<TextField::Type>& property) { + bool expressionHasOverrides = false; + const auto checkExpression = [&](const expression::Expression& e) { + if (expressionHasOverrides) { + return; + } + + if (e.getKind() == expression::Kind::Literal && + e.getType() == expression::type::Formatted) { + const auto* literalExpr = static_cast<const expression::Literal*>(&e); + const auto formattedValue = expression::fromExpressionValue<expression::Formatted>(literalExpr->getValue()); + if (formattedValue && checkLiteral(*formattedValue)) { + expressionHasOverrides = true; + } + return; + } + + if (e.getKind() == expression::Kind::FormatExpression) { + const auto* formatExpr = static_cast<const expression::FormatExpression*>(&e); + for (const auto& section : formatExpr->getSections()) { + if (Property::hasOverride(section)) { + expressionHasOverrides = true; + break; + } } } + }; + + // Check root property expression and return early. + checkExpression(property.getExpression()); + if (expressionHasOverrides) { + return true; } - return false; + + // Traverse thru children and check whether any of them have overrides. + property.getExpression().eachChild(checkExpression); + return expressionHasOverrides; }, [] (const auto&) { return false; diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp index c352ab8e77..cf8a9ab0d0 100644 --- a/src/mbgl/style/layers/symbol_layer_properties.hpp +++ b/src/mbgl/style/layers/symbol_layer_properties.hpp @@ -147,6 +147,16 @@ struct TextJustify : DataDrivenLayoutProperty<TextJustifyType> { static TextJustifyType defaultValue() { return TextJustifyType::Center; } }; +struct TextRadialOffset : DataDrivenLayoutProperty<float> { + static constexpr const char *name() { return "text-radial-offset"; } + static float defaultValue() { return 0; } +}; + +struct TextVariableAnchor : LayoutProperty<std::vector<TextVariableAnchorType>> { + static constexpr const char *name() { return "text-variable-anchor"; } + static std::vector<TextVariableAnchorType> defaultValue() { return { }; } +}; + struct TextAnchor : DataDrivenLayoutProperty<SymbolAnchorType> { static constexpr const char *name() { return "text-anchor"; } static SymbolAnchorType defaultValue() { return SymbolAnchorType::Center; } @@ -197,23 +207,23 @@ struct TextOptional : LayoutProperty<bool> { static bool defaultValue() { return false; } }; -struct IconOpacity : DataDrivenPaintProperty<float, attributes::a_opacity, uniforms::u_opacity> { +struct IconOpacity : DataDrivenPaintProperty<float, attributes::opacity, uniforms::opacity> { static float defaultValue() { return 1; } }; -struct IconColor : DataDrivenPaintProperty<Color, attributes::a_fill_color, uniforms::u_fill_color> { +struct IconColor : DataDrivenPaintProperty<Color, attributes::fill_color, uniforms::fill_color> { static Color defaultValue() { return Color::black(); } }; -struct IconHaloColor : DataDrivenPaintProperty<Color, attributes::a_halo_color, uniforms::u_halo_color> { +struct IconHaloColor : DataDrivenPaintProperty<Color, attributes::halo_color, uniforms::halo_color> { static Color defaultValue() { return {}; } }; -struct IconHaloWidth : DataDrivenPaintProperty<float, attributes::a_halo_width, uniforms::u_halo_width> { +struct IconHaloWidth : DataDrivenPaintProperty<float, attributes::halo_width, uniforms::halo_width> { static float defaultValue() { return 0; } }; -struct IconHaloBlur : DataDrivenPaintProperty<float, attributes::a_halo_blur, uniforms::u_halo_blur> { +struct IconHaloBlur : DataDrivenPaintProperty<float, attributes::halo_blur, uniforms::halo_blur> { static float defaultValue() { return 0; } }; @@ -225,26 +235,26 @@ struct IconTranslateAnchor : PaintProperty<TranslateAnchorType> { static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; } }; -struct TextOpacity : DataDrivenPaintProperty<float, attributes::a_opacity, uniforms::u_opacity> { +struct TextOpacity : DataDrivenPaintProperty<float, attributes::opacity, uniforms::opacity> { static float defaultValue() { return 1; } }; -struct TextColor : DataDrivenPaintProperty<Color, attributes::a_fill_color, uniforms::u_fill_color, true> { +struct TextColor : DataDrivenPaintProperty<Color, attributes::fill_color, uniforms::fill_color, true> { static Color defaultValue() { return Color::black(); } static constexpr const char *name() { return "text-color"; } static constexpr auto expressionType() { return expression::type::ColorType{}; }; template<typename T> static bool hasOverride(const T& t) { return !!t.textColor; }; }; -struct TextHaloColor : DataDrivenPaintProperty<Color, attributes::a_halo_color, uniforms::u_halo_color> { +struct TextHaloColor : DataDrivenPaintProperty<Color, attributes::halo_color, uniforms::halo_color> { static Color defaultValue() { return {}; } }; -struct TextHaloWidth : DataDrivenPaintProperty<float, attributes::a_halo_width, uniforms::u_halo_width> { +struct TextHaloWidth : DataDrivenPaintProperty<float, attributes::halo_width, uniforms::halo_width> { static float defaultValue() { return 0; } }; -struct TextHaloBlur : DataDrivenPaintProperty<float, attributes::a_halo_blur, uniforms::u_halo_blur> { +struct TextHaloBlur : DataDrivenPaintProperty<float, attributes::halo_blur, uniforms::halo_blur> { static float defaultValue() { return 0; } }; @@ -284,6 +294,8 @@ class SymbolLayoutProperties : public Properties< TextLineHeight, TextLetterSpacing, TextJustify, + TextRadialOffset, + TextVariableAnchor, TextAnchor, TextMaxAngle, TextRotate, diff --git a/src/mbgl/style/sources/raster_dem_source.cpp b/src/mbgl/style/sources/raster_dem_source.cpp index dc9feb8eeb..bb745561b1 100644 --- a/src/mbgl/style/sources/raster_dem_source.cpp +++ b/src/mbgl/style/sources/raster_dem_source.cpp @@ -3,7 +3,6 @@ #include <mbgl/style/source_observer.hpp> #include <mbgl/style/conversion/json.hpp> #include <mbgl/style/conversion/tileset.hpp> -#include <mbgl/storage/file_source.hpp> #include <mbgl/util/mapbox.hpp> namespace mbgl { @@ -13,7 +12,5 @@ RasterDEMSource::RasterDEMSource(std::string id, variant<std::string, Tileset> u : RasterSource(std::move(id), urlOrTileset_, tileSize, SourceType::RasterDEM){ } - - } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/style_impl.cpp b/src/mbgl/style/style_impl.cpp index d65e9c9de2..fde5aa632d 100644 --- a/src/mbgl/style/style_impl.cpp +++ b/src/mbgl/style/style_impl.cpp @@ -254,6 +254,7 @@ bool Style::Impl::isLoaded() const { void Style::Impl::addImage(std::unique_ptr<style::Image> image) { images.remove(image->getID()); // We permit using addImage to update. images.add(std::move(image)); + observer->onUpdate(); } void Style::Impl::removeImage(const std::string& id) { diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp index 51174cf152..889f6029e2 100644 --- a/src/mbgl/style/types.cpp +++ b/src/mbgl/style/types.cpp @@ -76,13 +76,14 @@ MBGL_DEFINE_ENUM(SymbolAnchorType, { { SymbolAnchorType::BottomLeft, "bottom-left" }, { SymbolAnchorType::BottomRight, "bottom-right" } }); - + MBGL_DEFINE_ENUM(SymbolZOrderType, { { SymbolZOrderType::ViewportY, "viewport-y" }, { SymbolZOrderType::Source, "source" } }); MBGL_DEFINE_ENUM(TextJustifyType, { + { TextJustifyType::Auto, "auto" }, { TextJustifyType::Center, "center" }, { TextJustifyType::Left, "left" }, { TextJustifyType::Right, "right" }, diff --git a/src/mbgl/text/collision_index.cpp b/src/mbgl/text/collision_index.cpp index 90acb2b441..88e59bf51c 100644 --- a/src/mbgl/text/collision_index.cpp +++ b/src/mbgl/text/collision_index.cpp @@ -80,6 +80,7 @@ bool CollisionIndex::isInsideTile(const CollisionBox& box, const CollisionTileBo std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature, + Point<float> shift, const mat4& posMatrix, const mat4& labelPlaneMatrix, const float textPixelRatio, @@ -95,10 +96,10 @@ std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature, CollisionBox& box = feature.boxes.front(); const auto projectedPoint = projectAndGetPerspectiveRatio(posMatrix, box.anchor); const float tileToViewport = textPixelRatio * projectedPoint.second; - box.px1 = box.x1 * tileToViewport + projectedPoint.first.x; - box.py1 = box.y1 * tileToViewport + projectedPoint.first.y; - box.px2 = box.x2 * tileToViewport + projectedPoint.first.x; - box.py2 = box.y2 * tileToViewport + projectedPoint.first.y; + box.px1 = (box.x1 + shift.x) * tileToViewport + projectedPoint.first.x; + box.py1 = (box.y1 + shift.y) * tileToViewport + projectedPoint.first.y; + box.px2 = (box.x2 + shift.x) * tileToViewport + projectedPoint.first.x; + box.py2 = (box.y2 + shift.y) * tileToViewport + projectedPoint.first.y; if ((avoidEdges && !isInsideTile(box, *avoidEdges)) || diff --git a/src/mbgl/text/collision_index.hpp b/src/mbgl/text/collision_index.hpp index dac0aa0bf7..dd160c945c 100644 --- a/src/mbgl/text/collision_index.hpp +++ b/src/mbgl/text/collision_index.hpp @@ -23,6 +23,7 @@ public: explicit CollisionIndex(const TransformState&); std::pair<bool,bool> placeFeature(CollisionFeature& feature, + Point<float> shift, const mat4& posMatrix, const mat4& labelPlaneMatrix, const float textPixelRatio, diff --git a/src/mbgl/text/glyph.hpp b/src/mbgl/text/glyph.hpp index c97b242c10..7d6415c057 100644 --- a/src/mbgl/text/glyph.hpp +++ b/src/mbgl/text/glyph.hpp @@ -78,15 +78,17 @@ enum class WritingModeType : uint8_t; class Shaping { public: - explicit Shaping() = default; - explicit Shaping(float x, float y, WritingModeType writingMode_) - : top(y), bottom(y), left(x), right(x), writingMode(writingMode_) {} + Shaping() = default; + explicit Shaping(float x, float y, WritingModeType writingMode_, std::size_t lineCount_) + : top(y), bottom(y), left(x), right(x), writingMode(writingMode_), lineCount(lineCount_) {} std::vector<PositionedGlyph> positionedGlyphs; float top = 0; float bottom = 0; float left = 0; float right = 0; WritingModeType writingMode; + std::size_t lineCount = 0u; + std::string text = {}; explicit operator bool() const { return !positionedGlyphs.empty(); } }; diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 4cc12b0980..f6c4ac1eb6 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -1,10 +1,13 @@ #include <mbgl/text/placement.hpp> + +#include <mbgl/layout/symbol_layout.hpp> #include <mbgl/renderer/render_layer.hpp> #include <mbgl/renderer/layers/render_layer_symbol_interface.hpp> #include <mbgl/renderer/render_tile.hpp> #include <mbgl/tile/geometry_tile.hpp> #include <mbgl/renderer/buckets/symbol_bucket.hpp> #include <mbgl/renderer/bucket.hpp> +#include <mbgl/util/math.hpp> namespace mbgl { @@ -55,13 +58,18 @@ const CollisionGroups::CollisionGroup& CollisionGroups::get(const std::string& s } } -Placement::Placement(const TransformState& state_, MapMode mapMode_, style::TransitionOptions transitionOptions_, const bool crossSourceCollisions) +Placement::Placement(const TransformState& state_, MapMode mapMode_, style::TransitionOptions transitionOptions_, const bool crossSourceCollisions, std::unique_ptr<Placement> prevPlacement_) : collisionIndex(state_) , state(state_) , mapMode(mapMode_) , transitionOptions(transitionOptions_) , collisionGroups(crossSourceCollisions) -{} + , prevPlacement(std::move(prevPlacement_)) +{ + if (prevPlacement) { + prevPlacement->prevPlacement.reset(); // Only hold on to one placement back + } +} void Placement::placeLayer(const RenderLayerSymbolInterface& symbolInterface, const mat4& projMatrix, bool showCollisionBoxes) { @@ -121,6 +129,19 @@ void Placement::placeLayer(const RenderLayerSymbolInterface& symbolInterface, co } } +namespace { +Point<float> calculateVariableLayoutOffset(style::SymbolAnchorType anchor, float width, float height, float radialOffset, float textBoxScale) { + AnchorAlignment alignment = AnchorAlignment::getAnchorAlignment(anchor); + float shiftX = -(alignment.horizontalAlign - 0.5f) * width; + float shiftY = -(alignment.verticalAlign - 0.5f) * height; + Point<float> offset = SymbolLayout::evaluateRadialOffset(anchor, radialOffset); + return Point<float>( + shiftX + offset.x * textBoxScale, + shiftY + offset.y * textBoxScale + ); +} +} // namespace + void Placement::placeLayerBucket( SymbolBucket& bucket, const mat4& posMatrix, @@ -161,8 +182,11 @@ void Placement::placeLayerBucket( // See https://github.com/mapbox/mapbox-gl-native/issues/12683 const bool alwaysShowText = textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || bucket.layout.get<style::IconOptional>()); const bool alwaysShowIcon = iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || bucket.layout.get<style::TextOptional>()); + std::vector<style::TextVariableAnchorType> variableTextAnchors = bucket.layout.get<style::TextVariableAnchor>(); + const bool rotateWithMap = bucket.layout.get<style::TextRotationAlignment>() == style::AlignmentType::Map; + const bool pitchWithMap = bucket.layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map; - for (auto& symbolInstance : bucket.symbolInstances) { + for (SymbolInstance& symbolInstance : bucket.symbolInstances) { if (seenCrossTileIDs.count(symbolInstance.crossTileID) == 0) { if (holdingForFade) { @@ -175,30 +199,111 @@ void Placement::placeLayerBucket( bool placeText = false; bool placeIcon = false; bool offscreen = true; - - if (symbolInstance.placedTextIndex) { - PlacedSymbol& placedSymbol = bucket.text.placedSymbols.at(*symbolInstance.placedTextIndex); + optional<size_t> horizontalTextIndex = symbolInstance.getDefaultHorizontalPlacedTextIndex(); + if (horizontalTextIndex) { + CollisionFeature& textCollisionFeature = symbolInstance.textCollisionFeature; + PlacedSymbol& placedSymbol = bucket.text.placedSymbols.at(*horizontalTextIndex); const float fontSize = evaluateSizeForFeature(partiallyEvaluatedTextSize, placedSymbol); - - auto placed = collisionIndex.placeFeature(symbolInstance.textCollisionFeature, - posMatrix, textLabelPlaneMatrix, textPixelRatio, - placedSymbol, scale, fontSize, - bucket.layout.get<style::TextAllowOverlap>(), - bucket.layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map, - showCollisionBoxes, avoidEdges, collisionGroup.second); - placeText = placed.first; - offscreen &= placed.second; + if (variableTextAnchors.empty()) { + auto placed = collisionIndex.placeFeature(textCollisionFeature, {}, + posMatrix, textLabelPlaneMatrix, textPixelRatio, + placedSymbol, scale, fontSize, + bucket.layout.get<style::TextAllowOverlap>(), + pitchWithMap, + showCollisionBoxes, avoidEdges, collisionGroup.second); + placeText = placed.first; + offscreen &= placed.second; + } else if (!textCollisionFeature.alongLine && !textCollisionFeature.boxes.empty()) { + const CollisionBox& textBox = symbolInstance.textCollisionFeature.boxes[0]; + const float width = textBox.x2 - textBox.x1; + const float height = textBox.y2 - textBox.y1; + const float textBoxScale = symbolInstance.textBoxScale; + + // If this symbol was in the last placement, shift the previously used + // anchor to the front of the anchor list. + if (prevPlacement) { + auto prevOffset = prevPlacement->variableOffsets.find(symbolInstance.crossTileID); + if (prevOffset != prevPlacement->variableOffsets.end() && + variableTextAnchors.front() != prevOffset->second.anchor) { + std::vector<style::TextVariableAnchorType> filtered; + filtered.reserve(variableTextAnchors.size()); + filtered.push_back(prevOffset->second.anchor); + for (auto anchor : variableTextAnchors) { + if (anchor != prevOffset->second.anchor) { + filtered.push_back(anchor); + } + } + variableTextAnchors = std::move(filtered); + } + } + + for (auto anchor : variableTextAnchors) { + Point<float> shift = calculateVariableLayoutOffset(anchor, width, height, symbolInstance.radialTextOffset, textBoxScale); + if (rotateWithMap) { + float angle = pitchWithMap ? state.getBearing() : -state.getBearing(); + shift = util::rotate(shift, angle); + } + + auto placed = collisionIndex.placeFeature(textCollisionFeature, shift, + posMatrix, mat4(), textPixelRatio, + placedSymbol, scale, fontSize, + bucket.layout.get<style::TextAllowOverlap>(), + pitchWithMap, + showCollisionBoxes, avoidEdges, collisionGroup.second); + + if (placed.first) { + assert(symbolInstance.crossTileID != 0u); + optional<style::TextVariableAnchorType> prevAnchor; + + // If this label was placed in the previous placement, record the anchor position + // to allow us to animate the transition + if (prevPlacement) { + auto prevOffset = prevPlacement->variableOffsets.find(symbolInstance.crossTileID); + auto prevPlacements = prevPlacement->placements.find(symbolInstance.crossTileID); + if (prevOffset != prevPlacement->variableOffsets.end() && + prevPlacements != prevPlacement->placements.end() && + prevPlacements->second.text) { + prevAnchor = prevOffset->second.anchor; + } + } + + variableOffsets.insert(std::make_pair(symbolInstance.crossTileID, VariableOffset{ + symbolInstance.radialTextOffset, + width, + height, + anchor, + textBoxScale, + prevAnchor + })); + markUsedJustification(bucket, anchor, symbolInstance); + + placeText = placed.first; + offscreen &= placed.second; + break; + } + } + + // If we didn't get placed, we still need to copy our position from the last placement for + // fade animations + if (prevPlacement && variableOffsets.find(symbolInstance.crossTileID) == variableOffsets.end()) { + auto prevOffset = prevPlacement->variableOffsets.find(symbolInstance.crossTileID); + if (prevOffset != prevPlacement->variableOffsets.end()) { + variableOffsets[symbolInstance.crossTileID] = prevOffset->second; + markUsedJustification(bucket, prevOffset->second.anchor, symbolInstance); + } + } + } } if (symbolInstance.placedIconIndex) { PlacedSymbol& placedSymbol = bucket.icon.placedSymbols.at(*symbolInstance.placedIconIndex); const float fontSize = evaluateSizeForFeature(partiallyEvaluatedIconSize, placedSymbol); - auto placed = collisionIndex.placeFeature(symbolInstance.iconCollisionFeature, + auto placed = collisionIndex.placeFeature(symbolInstance.iconCollisionFeature, {}, posMatrix, iconLabelPlaneMatrix, textPixelRatio, placedSymbol, scale, fontSize, bucket.layout.get<style::IconAllowOverlap>(), - bucket.layout.get<style::IconPitchAlignment>() == style::AlignmentType::Map, + pitchWithMap, showCollisionBoxes, avoidEdges, collisionGroup.second); placeIcon = placed.first; offscreen &= placed.second; @@ -240,7 +345,8 @@ void Placement::placeLayerBucket( bucket.justReloaded = false; } -void Placement::commit(const Placement& prevPlacement, TimePoint now) { +void Placement::commit(TimePoint now) { + assert(prevPlacement); commitTime = now; bool placementChanged = false; @@ -248,13 +354,13 @@ void Placement::commit(const Placement& prevPlacement, TimePoint now) { float increment = mapMode == MapMode::Continuous && transitionOptions.enablePlacementTransitions && transitionOptions.duration.value_or(util::DEFAULT_TRANSITION_DURATION) > Milliseconds(0) ? - std::chrono::duration<float>(commitTime - prevPlacement.commitTime) / transitionOptions.duration.value_or(util::DEFAULT_TRANSITION_DURATION) : + std::chrono::duration<float>(commitTime - prevPlacement->commitTime) / transitionOptions.duration.value_or(util::DEFAULT_TRANSITION_DURATION) : 1.0; // add the opacities from the current placement, and copy their current values from the previous placement for (auto& jointPlacement : placements) { - auto prevOpacity = prevPlacement.opacities.find(jointPlacement.first); - if (prevOpacity != prevPlacement.opacities.end()) { + auto prevOpacity = prevPlacement->opacities.find(jointPlacement.first); + if (prevOpacity != prevPlacement->opacities.end()) { opacities.emplace(jointPlacement.first, JointOpacityState(prevOpacity->second, increment, jointPlacement.second.text, jointPlacement.second.icon)); placementChanged = placementChanged || jointPlacement.second.icon != prevOpacity->second.icon.placed || @@ -266,7 +372,7 @@ void Placement::commit(const Placement& prevPlacement, TimePoint now) { } // copy and update values from the previous placement that aren't in the current placement but haven't finished fading - for (auto& prevOpacity : prevPlacement.opacities) { + for (auto& prevOpacity : prevPlacement->opacities) { if (opacities.find(prevOpacity.first) == opacities.end()) { JointOpacityState jointOpacity(prevOpacity.second, increment, false, false); if (!jointOpacity.isHidden()) { @@ -276,7 +382,16 @@ void Placement::commit(const Placement& prevPlacement, TimePoint now) { } } - fadeStartTime = placementChanged ? commitTime : prevPlacement.fadeStartTime; + for (auto& prevOffset : prevPlacement->variableOffsets) { + const uint32_t crossTileID = prevOffset.first; + auto foundOffset = variableOffsets.find(crossTileID); + auto foundOpacity = opacities.find(crossTileID); + if (foundOffset == variableOffsets.end() && foundOpacity != opacities.end() && !foundOpacity->second.isHidden()) { + variableOffsets[prevOffset.first] = prevOffset.second; + } + } + + fadeStartTime = placementChanged ? commitTime : prevPlacement->fadeStartTime; } void Placement::updateLayerOpacities(const RenderLayerSymbolInterface& symbolInterface) { @@ -310,7 +425,10 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>& const bool textAllowOverlap = bucket.layout.get<style::TextAllowOverlap>(); const bool iconAllowOverlap = bucket.layout.get<style::IconAllowOverlap>(); - + const bool variablePlacement = !bucket.layout.get<style::TextVariableAnchor>().empty(); + const bool rotateWithMap = bucket.layout.get<style::TextRotationAlignment>() == style::AlignmentType::Map; + const bool pitchWithMap = bucket.layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map; + // If allow-overlap is true, we can show symbols before placement runs on them // But we have to wait for placement if we potentially depend on a paired icon/text // with allow-overlap: false. @@ -339,18 +457,38 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>& if (symbolInstance.hasText) { auto opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity); - for (size_t i = 0; i < symbolInstance.horizontalGlyphQuads.size() * 4; i++) { - bucket.text.opacityVertices.emplace_back(opacityVertex); + if (symbolInstance.placedRightTextIndex) { + for (size_t i = 0; i < symbolInstance.rightJustifiedGlyphQuads.size() * 4; i++) { + bucket.text.opacityVertices.emplace_back(opacityVertex); + } + PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedRightTextIndex]; + placed.hidden = opacityState.isHidden(); } - for (size_t i = 0; i < symbolInstance.verticalGlyphQuads.size() * 4; i++) { - bucket.text.opacityVertices.emplace_back(opacityVertex); + if (symbolInstance.placedCenterTextIndex && !symbolInstance.singleLine) { + for (size_t i = 0; i < symbolInstance.centerJustifiedGlyphQuads.size() * 4; i++) { + bucket.text.opacityVertices.emplace_back(opacityVertex); + } + PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedCenterTextIndex]; + placed.hidden = opacityState.isHidden(); } - if (symbolInstance.placedTextIndex) { - bucket.text.placedSymbols[*symbolInstance.placedTextIndex].hidden = opacityState.isHidden(); + if (symbolInstance.placedLeftTextIndex && !symbolInstance.singleLine) { + for (size_t i = 0; i < symbolInstance.leftJustifiedGlyphQuads.size() * 4; i++) { + bucket.text.opacityVertices.emplace_back(opacityVertex); + } + PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedLeftTextIndex]; + placed.hidden = opacityState.isHidden(); } if (symbolInstance.placedVerticalTextIndex) { + for (size_t i = 0; i < symbolInstance.verticalGlyphQuads.size() * 4; i++) { + bucket.text.opacityVertices.emplace_back(opacityVertex); + } bucket.text.placedSymbols[*symbolInstance.placedVerticalTextIndex].hidden = opacityState.isHidden(); } + + auto prevOffset = variableOffsets.find(symbolInstance.crossTileID); + if (prevOffset != variableOffsets.end()) { + markUsedJustification(bucket, prevOffset->second.anchor, symbolInstance); + } } if (symbolInstance.hasIcon) { auto opacityVertex = SymbolIconProgram::opacityVertex(opacityState.icon.placed, opacityState.icon.opacity); @@ -369,7 +507,42 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>& if (feature.alongLine) { return; } - auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false); + auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false, {}); + for (size_t i = 0; i < feature.boxes.size() * 4; i++) { + bucket.collisionBox.dynamicVertices.emplace_back(dynamicVertex); + } + }; + + auto updateCollisionTextBox = [this, &bucket, &symbolInstance, variablePlacement, rotateWithMap, pitchWithMap](const auto& feature, const bool placed) { + if (feature.alongLine) { + return; + } + Point<float> shift; + bool used = true; + if (variablePlacement) { + auto foundOffset = variableOffsets.find(symbolInstance.crossTileID); + if (foundOffset != variableOffsets.end()) { + const VariableOffset& variableOffset = foundOffset->second; + // This will show either the currently placed position or the last + // successfully placed position (so you can visualize what collision + // just made the symbol disappear, and the most likely place for the + // symbol to come back) + shift = calculateVariableLayoutOffset(variableOffset.anchor, + variableOffset.width, + variableOffset.height, + variableOffset.radialOffset, + variableOffset.textBoxScale); + if (rotateWithMap) { + shift = util::rotate(shift, pitchWithMap ? state.getBearing() : -state.getBearing()); + } + } else { + // No offset -> this symbol hasn't been placed since coming on-screen + // No single box is particularly meaningful and all of them would be too noisy + // Use the center box just to show something's there, but mark it "not used" + used = false; + } + } + auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !used, shift); for (size_t i = 0; i < feature.boxes.size() * 4; i++) { bucket.collisionBox.dynamicVertices.emplace_back(dynamicVertex); } @@ -380,7 +553,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>& return; } for (const CollisionBox& box : feature.boxes) { - auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !box.used); + auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !box.used, {}); bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex); bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex); bucket.collisionCircle.dynamicVertices.emplace_back(dynamicVertex); @@ -389,7 +562,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>& }; if (bucket.hasCollisionBoxData()) { - updateCollisionBox(symbolInstance.textCollisionFeature, opacityState.text.placed); + updateCollisionTextBox(symbolInstance.textCollisionFeature, opacityState.text.placed); updateCollisionBox(symbolInstance.iconCollisionFeature, opacityState.icon.placed); } if (bucket.hasCollisionCircleData()) { @@ -406,6 +579,31 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>& } } +void Placement::markUsedJustification(SymbolBucket& bucket, style::TextVariableAnchorType placedAnchor, SymbolInstance& symbolInstance) { + std::map<style::TextJustifyType, optional<size_t>> justificationToIndex { + {style::TextJustifyType::Right, symbolInstance.placedRightTextIndex}, + {style::TextJustifyType::Center, symbolInstance.placedCenterTextIndex}, + {style::TextJustifyType::Left, symbolInstance.placedLeftTextIndex}, + }; + style::TextJustifyType justify = getAnchorJustification(placedAnchor); + assert(justify == style::TextJustifyType::Right || justify == style::TextJustifyType::Center || justify == style::TextJustifyType::Left); + const optional<size_t> autoIndex = justificationToIndex[justify]; + + for (auto& pair : justificationToIndex) { + const optional<size_t> index = pair.second; + if (index) { + assert(bucket.text.placedSymbols.size() > *index); + if (autoIndex && *index != *autoIndex) { + // There are multiple justifications and this one isn't it: shift offscreen + bucket.text.placedSymbols.at(*index).crossTileID = 0u; + } else { + // Either this is the chosen justification or the justification is hardwired: use this one + bucket.text.placedSymbols.at(*index).crossTileID = symbolInstance.crossTileID; + } + } + } +} + float Placement::symbolFadeChange(TimePoint now) const { if (mapMode == MapMode::Continuous && transitionOptions.enablePlacementTransitions && transitionOptions.duration.value_or(util::DEFAULT_TRANSITION_DURATION) > Milliseconds(0)) { diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index cc23110e54..3f2a7b8a03 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -12,6 +12,7 @@ namespace mbgl { class RenderLayerSymbolInterface; class SymbolBucket; +class SymbolInstance; class OpacityState { public: @@ -31,6 +32,16 @@ public: OpacityState text; }; +class VariableOffset { +public: + float radialOffset; + float width; + float height; + style::TextVariableAnchorType anchor; + float textBoxScale; + optional<style::TextVariableAnchorType> prevAnchor; +}; + class JointPlacement { public: JointPlacement(bool text_, bool icon_, bool skipFade_) @@ -45,7 +56,7 @@ public: // visible right away. const bool skipFade; }; - + struct RetainedQueryData { uint32_t bucketInstanceId; std::shared_ptr<FeatureIndex> featureIndex; @@ -80,9 +91,9 @@ private: class Placement { public: - Placement(const TransformState&, MapMode, style::TransitionOptions, const bool crossSourceCollisions); + Placement(const TransformState&, MapMode, style::TransitionOptions, const bool crossSourceCollisions, std::unique_ptr<Placement> prevPlacementOrNull = nullptr); void placeLayer(const RenderLayerSymbolInterface&, const mat4&, bool showCollisionBoxes); - void commit(const Placement& prevPlacement, TimePoint); + void commit(TimePoint); void updateLayerOpacities(const RenderLayerSymbolInterface&); float symbolFadeChange(TimePoint now) const; bool hasTransitions(TimePoint now) const; @@ -94,8 +105,10 @@ public: void setStale(); const RetainedQueryData& getQueryData(uint32_t bucketInstanceId) const; -private: + using VariableOffsets = std::reference_wrapper<const std::unordered_map<uint32_t, VariableOffset>>; + VariableOffsets getVariableOffsets() const { return std::cref(variableOffsets); } +private: void placeLayerBucket( SymbolBucket&, const mat4& posMatrix, @@ -109,6 +122,7 @@ private: const CollisionGroups::CollisionGroup& collisionGroup); void updateBucketOpacities(SymbolBucket&, std::set<uint32_t>&); + void markUsedJustification(SymbolBucket&, style::TextVariableAnchorType, SymbolInstance&); CollisionIndex collisionIndex; @@ -121,11 +135,13 @@ private: std::unordered_map<uint32_t, JointPlacement> placements; std::unordered_map<uint32_t, JointOpacityState> opacities; + std::unordered_map<uint32_t, VariableOffset> variableOffsets; bool stale = false; std::unordered_map<uint32_t, RetainedQueryData> retainedQueryData; CollisionGroups collisionGroups; + std::unique_ptr<Placement> prevPlacement; }; } // namespace mbgl diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index ec0045caad..6be5d8c01e 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -92,16 +92,12 @@ SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, } SymbolQuads getGlyphQuads(const Shaping& shapedText, + const std::array<float, 2> textOffset, const SymbolLayoutProperties::Evaluated& layout, const style::SymbolPlacementType placement, const GlyphPositions& positions) { const float textRotate = layout.get<TextRotate>() * util::DEG2RAD; - const float oneEm = 24.0; - std::array<float, 2> textOffset = layout.get<TextOffset>(); - textOffset[0] *= oneEm; - textOffset[1] *= oneEm; - SymbolQuads quads; for (const PositionedGlyph &positionedGlyph: shapedText.positionedGlyphs) { diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index f41a4fec66..0bb892e4d1 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -49,6 +49,7 @@ SymbolQuad getIconQuad(const PositionedIcon& shapedIcon, const Shaping& shapedText); SymbolQuads getGlyphQuads(const Shaping& shapedText, + const std::array<float, 2> textOffset, const style::SymbolLayoutProperties::Evaluated&, style::SymbolPlacementType placement, const GlyphPositions& positions); diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp index 02dbf146e1..ba21b97389 100644 --- a/src/mbgl/text/shaping.cpp +++ b/src/mbgl/text/shaping.cpp @@ -1,4 +1,5 @@ #include <mbgl/text/shaping.hpp> +#include <mbgl/util/constants.hpp> #include <mbgl/util/i18n.hpp> #include <mbgl/layout/symbol_feature.hpp> #include <mbgl/math/minmax.hpp> @@ -10,58 +11,61 @@ namespace mbgl { -struct AnchorAlignment { - AnchorAlignment(float horizontal_, float vertical_) - : horizontalAlign(horizontal_), verticalAlign(vertical_) { - } - - float horizontalAlign; - float verticalAlign; -}; -AnchorAlignment getAnchorAlignment(style::SymbolAnchorType anchor) { - float horizontalAlign = 0.5; - float verticalAlign = 0.5; +// static +AnchorAlignment AnchorAlignment::getAnchorAlignment(style::SymbolAnchorType anchor) { + AnchorAlignment result(0.5f, 0.5f); switch (anchor) { - case style::SymbolAnchorType::Top: - case style::SymbolAnchorType::Bottom: - case style::SymbolAnchorType::Center: - break; case style::SymbolAnchorType::Right: case style::SymbolAnchorType::TopRight: case style::SymbolAnchorType::BottomRight: - horizontalAlign = 1; + result.horizontalAlign = 1.0f; break; case style::SymbolAnchorType::Left: case style::SymbolAnchorType::TopLeft: case style::SymbolAnchorType::BottomLeft: - horizontalAlign = 0; + result.horizontalAlign = 0.0f; break; + default: + break; } switch (anchor) { - case style::SymbolAnchorType::Left: - case style::SymbolAnchorType::Right: - case style::SymbolAnchorType::Center: - break; case style::SymbolAnchorType::Bottom: case style::SymbolAnchorType::BottomLeft: case style::SymbolAnchorType::BottomRight: - verticalAlign = 1; + result.verticalAlign = 1.0f; break; case style::SymbolAnchorType::Top: case style::SymbolAnchorType::TopLeft: case style::SymbolAnchorType::TopRight: - verticalAlign = 0; + result.verticalAlign = 0.0f; + break; + default: break; } - return AnchorAlignment(horizontalAlign, verticalAlign); + return result; +} + +style::TextJustifyType getAnchorJustification(style::SymbolAnchorType anchor) { + switch (anchor) { + case style::SymbolAnchorType::Right: + case style::SymbolAnchorType::TopRight: + case style::SymbolAnchorType::BottomRight: + return style::TextJustifyType::Right; + case style::SymbolAnchorType::Left: + case style::SymbolAnchorType::TopLeft: + case style::SymbolAnchorType::BottomLeft: + return style::TextJustifyType::Left; + default: + return style::TextJustifyType::Center; + } } PositionedIcon PositionedIcon::shapeIcon(const ImagePosition& image, const std::array<float, 2>& iconOffset, style::SymbolAnchorType iconAnchor, const float iconRotation) { - AnchorAlignment anchorAlign = getAnchorAlignment(iconAnchor); + AnchorAlignment anchorAlign = AnchorAlignment::getAnchorAlignment(iconAnchor); float dx = iconOffset[0]; float dy = iconOffset[1]; float x1 = dx - image.displaySize()[0] * anchorAlign.horizontalAlign; @@ -269,7 +273,6 @@ void shapeLines(Shaping& shaping, const float lineHeight, const style::SymbolAnchorType textAnchor, const style::TextJustifyType textJustify, - const float verticalHeight, const WritingModeType writingMode, const GlyphMap& glyphMap) { @@ -314,7 +317,7 @@ void shapeLines(Shaping& shaping, // We don't know the baseline, but since we're laying out // at 24 points, we can calculate how much it will move when // we scale up or down. - const double baselineOffset = (lineMaxScale - section.scale) * 24; + const double baselineOffset = (lineMaxScale - section.scale) * util::ONE_EM; const Glyph& glyph = **it->second; @@ -323,7 +326,7 @@ void shapeLines(Shaping& shaping, x += glyph.metrics.advance * section.scale + spacing; } else { shaping.positionedGlyphs.emplace_back(codePoint, x, baselineOffset, true, section.fontStackHash, section.scale, sectionIndex); - x += verticalHeight * section.scale + spacing; + x += util::ONE_EM * section.scale + spacing; } } @@ -340,7 +343,7 @@ void shapeLines(Shaping& shaping, y += lineHeight * lineMaxScale; } - auto anchorAlign = getAnchorAlignment(textAnchor); + auto anchorAlign = AnchorAlignment::getAnchorAlignment(textAnchor); align(shaping, justify, anchorAlign.horizontalAlign, anchorAlign.verticalAlign, maxLineLength, lineHeight, lines.size()); @@ -360,12 +363,9 @@ const Shaping getShaping(const TaggedString& formattedString, const style::TextJustifyType textJustify, const float spacing, const Point<float>& translate, - const float verticalHeight, const WritingModeType writingMode, BiDi& bidi, - const GlyphMap& glyphs) { - Shaping shaping(translate.x, translate.y, writingMode); - + const GlyphMap& glyphs) { std::vector<TaggedString> reorderedLines; if (formattedString.sectionCount() == 1) { auto untaggedLines = bidi.processText(formattedString.rawText(), @@ -380,9 +380,9 @@ const Shaping getShaping(const TaggedString& formattedString, reorderedLines.emplace_back(line, formattedString.getSections()); } } - + Shaping shaping(translate.x, translate.y, writingMode, reorderedLines.size()); shapeLines(shaping, reorderedLines, spacing, lineHeight, textAnchor, - textJustify, verticalHeight, writingMode, glyphs); + textJustify, writingMode, glyphs); return shaping; } diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp index 50ac893098..766b1ce233 100644 --- a/src/mbgl/text/shaping.hpp +++ b/src/mbgl/text/shaping.hpp @@ -7,6 +7,20 @@ namespace mbgl { +struct AnchorAlignment { + AnchorAlignment(float horizontal, float vertical) + : horizontalAlign(horizontal), verticalAlign(vertical) { + } + + static AnchorAlignment getAnchorAlignment(style::SymbolAnchorType anchor); + + float horizontalAlign; + float verticalAlign; +}; + +// Choose the justification that matches the direction of the TextAnchor +style::TextJustifyType getAnchorJustification(style::SymbolAnchorType anchor); + class SymbolFeature; class BiDi; @@ -53,7 +67,6 @@ const Shaping getShaping(const TaggedString& string, style::TextJustifyType textJustify, float spacing, const Point<float>& translate, - float verticalHeight, const WritingModeType, BiDi& bidi, const GlyphMap& glyphs); diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index c8498976b8..9165c03267 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -13,7 +13,6 @@ #include <mbgl/renderer/query.hpp> #include <mbgl/text/glyph_atlas.hpp> #include <mbgl/renderer/image_atlas.hpp> -#include <mbgl/storage/file_source.hpp> #include <mbgl/geometry/feature_index.hpp> #include <mbgl/map/transform_state.hpp> #include <mbgl/util/logging.hpp> @@ -157,8 +156,8 @@ void GeometryTile::getGlyphs(GlyphDependencies glyphDependencies) { glyphManager.getGlyphs(*this, std::move(glyphDependencies)); } -void GeometryTile::onImagesAvailable(ImageMap images, ImageMap patterns, uint64_t imageCorrelationID) { - worker.self().invoke(&GeometryTileWorker::onImagesAvailable, std::move(images), std::move(patterns), imageCorrelationID); +void GeometryTile::onImagesAvailable(ImageMap images, ImageMap patterns, ImageVersionMap versionMap, uint64_t imageCorrelationID) { + worker.self().invoke(&GeometryTileWorker::onImagesAvailable, std::move(images), std::move(patterns), std::move(versionMap), imageCorrelationID); } void GeometryTile::getImages(ImageRequestPair pair) { @@ -193,6 +192,10 @@ void GeometryTile::upload(gfx::Context& context) { iconAtlasTexture = context.createTexture(iconAtlas.image); iconAtlas.image = {}; } + + if (iconAtlasTexture) { + iconAtlas.patchUpdatedImages(context, *iconAtlasTexture, imageManager); + } } Bucket* GeometryTile::getBucket(const Layer::Impl& layer) const { diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index b652e7ba5d..53a8910c27 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -37,7 +37,7 @@ public: void setShowCollisionBoxes(const bool showCollisionBoxes) override; void onGlyphsAvailable(GlyphMap) override; - void onImagesAvailable(ImageMap, ImageMap, uint64_t imageCorrelationID) override; + void onImagesAvailable(ImageMap, ImageMap, ImageVersionMap versionMap, uint64_t imageCorrelationID) override; void getGlyphs(GlyphDependencies); void getImages(ImageRequestPair); diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index 943e782af1..0b703cd68b 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -278,12 +278,13 @@ void GeometryTileWorker::onGlyphsAvailable(GlyphMap newGlyphMap) { symbolDependenciesChanged(); } -void GeometryTileWorker::onImagesAvailable(ImageMap newIconMap, ImageMap newPatternMap, uint64_t imageCorrelationID_) { +void GeometryTileWorker::onImagesAvailable(ImageMap newIconMap, ImageMap newPatternMap, ImageVersionMap newVersionMap, uint64_t imageCorrelationID_) { if (imageCorrelationID != imageCorrelationID_) { return; // Ignore outdated image request replies. } imageMap = std::move(newIconMap); patternMap = std::move(newPatternMap); + versionMap = std::move(newVersionMap); pendingImageDependencies.clear(); symbolDependenciesChanged(); } @@ -441,7 +442,7 @@ void GeometryTileWorker::finalizeLayout() { MBGL_TIMING_START(watch) optional<AlphaImage> glyphAtlasImage; - ImageAtlas iconAtlas = makeImageAtlas(imageMap, patternMap); + ImageAtlas iconAtlas = makeImageAtlas(imageMap, patternMap, versionMap); if (!layouts.empty()) { GlyphAtlas glyphAtlas = makeGlyphAtlas(glyphMap); glyphAtlasImage = std::move(glyphAtlas.image); diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp index 485d1315a6..706bac0154 100644 --- a/src/mbgl/tile/geometry_tile_worker.hpp +++ b/src/mbgl/tile/geometry_tile_worker.hpp @@ -44,7 +44,7 @@ public: void setShowCollisionBoxes(bool showCollisionBoxes_, uint64_t correlationID_); void onGlyphsAvailable(GlyphMap glyphs); - void onImagesAvailable(ImageMap icons, ImageMap patterns, uint64_t imageCorrelationID); + void onImagesAvailable(ImageMap icons, ImageMap patterns, ImageVersionMap versionMap, uint64_t imageCorrelationID); private: void coalesced(); @@ -96,6 +96,7 @@ private: GlyphMap glyphMap; ImageMap imageMap; ImageMap patternMap; + ImageVersionMap versionMap; bool showCollisionBoxes; bool firstLoad = true; diff --git a/src/mbgl/tile/raster_dem_tile.cpp b/src/mbgl/tile/raster_dem_tile.cpp index ba961853d0..224c5c9062 100644 --- a/src/mbgl/tile/raster_dem_tile.cpp +++ b/src/mbgl/tile/raster_dem_tile.cpp @@ -5,7 +5,6 @@ #include <mbgl/style/source.hpp> #include <mbgl/storage/resource.hpp> #include <mbgl/storage/response.hpp> -#include <mbgl/storage/file_source.hpp> #include <mbgl/renderer/tile_parameters.hpp> #include <mbgl/renderer/buckets/hillshade_bucket.hpp> #include <mbgl/actor/scheduler.hpp> diff --git a/src/mbgl/tile/raster_tile.cpp b/src/mbgl/tile/raster_tile.cpp index 22561ec11d..ff02301021 100644 --- a/src/mbgl/tile/raster_tile.cpp +++ b/src/mbgl/tile/raster_tile.cpp @@ -5,7 +5,6 @@ #include <mbgl/style/source.hpp> #include <mbgl/storage/resource.hpp> #include <mbgl/storage/response.hpp> -#include <mbgl/storage/file_source.hpp> #include <mbgl/renderer/tile_parameters.hpp> #include <mbgl/renderer/buckets/raster_bucket.hpp> #include <mbgl/actor/scheduler.hpp> diff --git a/src/mbgl/util/literal.hpp b/src/mbgl/util/literal.hpp new file mode 100644 index 0000000000..d4fec49b35 --- /dev/null +++ b/src/mbgl/util/literal.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include <utility> +#include <cstddef> + +namespace mbgl { + +// Using structs instead of constexpr templates because GCC 4.9 doesn't support these yet. + +template <char... Cs> +struct string_literal { + static constexpr const char chars[] = { Cs..., 0 }; + + static constexpr const char* value() { + return chars; + } +}; + +template <char... Cs> +constexpr const char string_literal<Cs...>::chars[]; + +namespace detail { + +using string_fn = const char* (*)(); + +template <string_fn name, std::size_t... Is> +string_literal<name()[Is]...> to_string_literal(std::index_sequence<Is...>); + +constexpr std::size_t string_length(const char* const str, std::size_t len = 0) { + return str[0] ? string_length(str + 1, len + 1) : len; +} + +template <class...> +struct concat_literals; + +template <> +struct concat_literals<> { + static constexpr auto value() { + return ""; + } +}; + +template <char... As, char... Bs, class... Rest> +struct concat_literals<string_literal<As...>, string_literal<Bs...>, Rest...> { + static constexpr auto value() { + return concat_literals<string_literal<As..., Bs...>, Rest...>::value(); + } +}; + +template <char... Cs> +struct concat_literals<string_literal<Cs...>> { + static constexpr auto value() { + return string_literal<Cs...>::value(); + } +}; + +} // namespace detail + +template <detail::string_fn... str> +struct concat_literals { + static constexpr auto value() { + return detail::concat_literals<decltype(detail::to_string_literal<str>( + std::make_index_sequence<detail::string_length(str())>()))...>::value(); + } +}; + +} // namespace mbgl diff --git a/src/mbgl/util/offscreen_texture.cpp b/src/mbgl/util/offscreen_texture.cpp index 2a58ff86a3..6bc09c7b16 100644 --- a/src/mbgl/util/offscreen_texture.cpp +++ b/src/mbgl/util/offscreen_texture.cpp @@ -62,18 +62,20 @@ private: const gfx::TextureChannelDataType type; }; -OffscreenTexture::OffscreenTexture(gl::Context& context, +OffscreenTexture::OffscreenTexture(gfx::Context& context, const Size size, const gfx::TextureChannelDataType type) - : impl(std::make_unique<Impl>(context, std::move(size), type)) { + // TODO: remove cast + : impl(std::make_unique<Impl>(reinterpret_cast<gl::Context&>(context), std::move(size), type)) { assert(!size.isEmpty()); } -OffscreenTexture::OffscreenTexture(gl::Context& context, +OffscreenTexture::OffscreenTexture(gfx::Context& context, const Size size, gl::Renderbuffer<gl::RenderbufferType::DepthComponent>& renderbuffer, const gfx::TextureChannelDataType type) - : impl(std::make_unique<Impl>(context, std::move(size), renderbuffer, type)) { + // TODO: remove cast + : impl(std::make_unique<Impl>(reinterpret_cast<gl::Context&>(context), std::move(size), renderbuffer, type)) { assert(!size.isEmpty()); } diff --git a/src/mbgl/util/offscreen_texture.hpp b/src/mbgl/util/offscreen_texture.hpp index 9446fabecf..f4459556b8 100644 --- a/src/mbgl/util/offscreen_texture.hpp +++ b/src/mbgl/util/offscreen_texture.hpp @@ -6,20 +6,17 @@ namespace mbgl { -namespace gl { -class Context; -} // namespace gl - namespace gfx { +class Context; class Texture; } // namespace gfx class OffscreenTexture { public: - OffscreenTexture(gl::Context&, + OffscreenTexture(gfx::Context&, Size size = { 256, 256 }, gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte); - OffscreenTexture(gl::Context&, + OffscreenTexture(gfx::Context&, Size size, gl::Renderbuffer<gl::RenderbufferType::DepthComponent>&, gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte); |