diff options
author | Molly Lloyd <molly@mapbox.com> | 2018-08-07 17:08:10 -0700 |
---|---|---|
committer | Molly Lloyd <molly@mapbox.com> | 2018-08-27 13:21:04 -0700 |
commit | 291165bb53604bf89c6db6ed99b86823dfe87f2d (patch) | |
tree | 4470bbc542b41fd7e8614554a33b60d95263c5e3 | |
parent | 8ec4fff810a6563a0ae5e3c4380079ac27d9d195 (diff) | |
download | qtlocation-mapboxgl-291165bb53604bf89c6db6ed99b86823dfe87f2d.tar.gz |
[core] add support for fill- and fill-extrusion-pattern dds
26 files changed, 280 insertions, 161 deletions
diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp index 279c2b791c..61a70a2991 100644 --- a/src/mbgl/layout/pattern_layout.hpp +++ b/src/mbgl/layout/pattern_layout.hpp @@ -4,7 +4,7 @@ namespace mbgl { -template <class B, class L> +template <class B> class PatternLayout { public: PatternLayout(const BucketParameters& parameters, @@ -16,16 +16,17 @@ public: zoom(parameters.tileID.overscaledZ), overscaling(parameters.tileID.overscaleFactor()) { - const L* renderLayer = layers.at(0)->as<L>(); - const typename L::StyleLayerImpl& leader = renderLayer->impl(); + using PatternLayer = typename B::RenderLayerType; + const auto renderLayer = layers.at(0)->as<PatternLayer>(); + const typename PatternLayer::StyleLayerImpl& leader = renderLayer->impl(); layout = leader.layout.evaluate(PropertyEvaluationParameters(zoom)); sourceLayerID = leader.sourceLayer; groupID = renderLayer->getID(); for (const auto& layer : layers) { - const typename B::PossiblyEvaluatedPaintProperties evaluatedProps = layer->as<L>()->paintProperties(); + const typename B::PossiblyEvaluatedPaintProperties evaluatedProps = layer->as<PatternLayer>()->paintProperties(); layerPaintProperties.emplace(layer->getID(), std::move(evaluatedProps)); - const auto patterns = evaluatedProps.template get<typename L::PatternProperty>().possibleOutputs(); + const auto patterns = evaluatedProps.template get<typename PatternLayer::PatternProperty>().possibleOutputs(); for (auto& pattern : patterns) { const auto patternString = pattern.value_or(""); diff --git a/src/mbgl/programs/fill_extrusion_program.cpp b/src/mbgl/programs/fill_extrusion_program.cpp index 1e11a254eb..2bdd0604d7 100644 --- a/src/mbgl/programs/fill_extrusion_program.cpp +++ b/src/mbgl/programs/fill_extrusion_program.cpp @@ -46,33 +46,25 @@ FillExtrusionUniforms::values(mat4 matrix, FillExtrusionPatternUniforms::Values FillExtrusionPatternUniforms::values(mat4 matrix, Size atlasSize, - const ImagePosition& a, - const ImagePosition& b, - const Faded<std::string>& fading, + const CrossfadeParameters& crossfade, const UnwrappedTileID& tileID, const TransformState& state, const float heightFactor, + const float pixelRatio, const EvaluatedLight& light) { + const auto tileRatio = 1 / tileID.pixelsToTileUnits(1, state.getIntegerZoom()); int32_t tileSizeAtNearestZoom = util::tileSize * state.zoomScale(state.getIntegerZoom() - tileID.canonical.z); int32_t pixelX = tileSizeAtNearestZoom * (tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z)); int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y; return FillExtrusionPatternUniforms::Values{ uniforms::u_matrix::Value( matrix ), - 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_scale::Value( {{pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale}} ), uniforms::u_texsize::Value( atlasSize ), - uniforms::u_mix::Value( fading.t ), + uniforms::u_fade::Value( crossfade.t ), uniforms::u_image::Value( 0 ), 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::u_height_factor::Value( heightFactor ), uniforms::u_lightcolor::Value( lightColor(light) ), uniforms::u_lightpos::Value( lightPosition(light, state) ), diff --git a/src/mbgl/programs/fill_extrusion_program.hpp b/src/mbgl/programs/fill_extrusion_program.hpp index c499e9ef2d..657238d4c0 100644 --- a/src/mbgl/programs/fill_extrusion_program.hpp +++ b/src/mbgl/programs/fill_extrusion_program.hpp @@ -46,20 +46,12 @@ struct FillExtrusionUniforms : gl::Uniforms< struct FillExtrusionPatternUniforms : gl::Uniforms< uniforms::u_matrix, - 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_scale, uniforms::u_texsize, - uniforms::u_mix, + uniforms::u_fade, uniforms::u_image, uniforms::u_pixel_coord_upper, uniforms::u_pixel_coord_lower, - uniforms::u_tile_units_to_pixels, uniforms::u_height_factor, uniforms::u_lightcolor, uniforms::u_lightpos, @@ -67,12 +59,11 @@ struct FillExtrusionPatternUniforms : gl::Uniforms< { static Values values(mat4, Size atlasSize, - const ImagePosition&, - const ImagePosition&, - const Faded<std::string>&, + const CrossfadeParameters&, const UnwrappedTileID&, const TransformState&, - const float, + const float heightFactor, + const float pixelRatio, const EvaluatedLight&); }; diff --git a/src/mbgl/programs/fill_program.cpp b/src/mbgl/programs/fill_program.cpp index e88ee26824..b072343e7a 100644 --- a/src/mbgl/programs/fill_program.cpp +++ b/src/mbgl/programs/fill_program.cpp @@ -14,12 +14,12 @@ FillPatternUniforms::Values FillPatternUniforms::values(mat4 matrix, Size framebufferSize, Size atlasSize, - const ImagePosition& a, - const ImagePosition& b, - const Faded<std::string>& fading, + const CrossfadeParameters& crossfade, const UnwrappedTileID& tileID, - const TransformState& state) + const TransformState& state, + const float pixelRatio) { + const auto tileRatio = 1 / tileID.pixelsToTileUnits(1, state.getIntegerZoom()); int32_t tileSizeAtNearestZoom = util::tileSize * state.zoomScale(state.getIntegerZoom() - tileID.canonical.z); int32_t pixelX = tileSizeAtNearestZoom * (tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z)); int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y; @@ -28,19 +28,11 @@ FillPatternUniforms::values(mat4 matrix, uniforms::u_matrix::Value( matrix ), uniforms::u_world::Value( framebufferSize ), 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_scale::Value({ {pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale} } ), + uniforms::u_fade::Value( crossfade.t ), uniforms::u_image::Value( 0 ), 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::u_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 ac478250fc..9c623fee22 100644 --- a/src/mbgl/programs/fill_program.hpp +++ b/src/mbgl/programs/fill_program.hpp @@ -32,28 +32,19 @@ struct FillPatternUniforms : gl::Uniforms< uniforms::u_matrix, uniforms::u_world, 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_scale, + uniforms::u_fade, uniforms::u_image, uniforms::u_pixel_coord_upper, - uniforms::u_pixel_coord_lower, - uniforms::u_tile_units_to_pixels> + uniforms::u_pixel_coord_lower> { static Values values(mat4 matrix, Size framebufferSize, Size atlasSize, - const ImagePosition&, - const ImagePosition&, - const Faded<std::string>&, + const CrossfadeParameters& crossfade, const UnwrappedTileID&, - const TransformState&); + const TransformState&, + const float pixelRatio); }; class FillProgram : public Program< diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp index a5ba3a5c91..3541a3bfae 100644 --- a/src/mbgl/programs/line_program.cpp +++ b/src/mbgl/programs/line_program.cpp @@ -87,7 +87,7 @@ LinePatternProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvalu const TransformState& state, const std::array<float, 2>& pixelsToGLUnits, const Size atlasSize, - const CrossfadeParameters crossfade, + const CrossfadeParameters& crossfade, const float pixelRatio) { const auto tileRatio = 1 / tile.id.pixelsToTileUnits(1, state.getIntegerZoom()); diff --git a/src/mbgl/programs/line_program.hpp b/src/mbgl/programs/line_program.hpp index 9707778f26..cc4ec8c764 100644 --- a/src/mbgl/programs/line_program.hpp +++ b/src/mbgl/programs/line_program.hpp @@ -24,7 +24,6 @@ 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_SCALAR(float, u_fade); 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); @@ -121,7 +120,7 @@ public: const TransformState&, const std::array<float, 2>& pixelsToGLUnits, Size atlasSize, - const CrossfadeParameters crossfade, + const CrossfadeParameters& crossfade, const float pixelRatio); }; diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp index 43d94df162..ab68e43c87 100644 --- a/src/mbgl/programs/uniforms.hpp +++ b/src/mbgl/programs/uniforms.hpp @@ -36,6 +36,7 @@ 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); diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp index a4d8ea6f43..c8fe5a2bc1 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_bucket.cpp @@ -27,21 +27,25 @@ using namespace style; struct GeometryTooLongException : std::exception {}; -FillBucket::FillBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) +FillBucket::FillBucket(const FillBucket::PossiblyEvaluatedLayoutProperties, + std::map<std::string, FillBucket::PossiblyEvaluatedPaintProperties> layerPaintProperties, + const float zoom, + const uint32_t) : Bucket(LayerType::Fill) { - for (const auto& layer : layers) { + + for (const auto& pair : layerPaintProperties) { paintPropertyBinders.emplace( std::piecewise_construct, - std::forward_as_tuple(layer->getID()), + std::forward_as_tuple(pair.first), std::forward_as_tuple( - layer->as<RenderFillLayer>()->evaluated, - parameters.tileID.overscaledZ)); + pair.second, + zoom)); } } void FillBucket::addFeature(const GeometryTileFeature& feature, const GeometryCollection& geometry, - const ImagePositions&) { + const ImagePositions& patternPositions) { for (auto& polygon : classifyRings(geometry)) { // Optimize polygons with many interior rings for earcut tesselation. limitHoles(polygon, 500); @@ -106,7 +110,7 @@ void FillBucket::addFeature(const GeometryTileFeature& feature, } for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.vertexSize(), {}); + pair.second.populateVertexVectors(feature, vertices.vertexSize(), patternPositions); } } diff --git a/src/mbgl/renderer/buckets/fill_bucket.hpp b/src/mbgl/renderer/buckets/fill_bucket.hpp index 8a83b27491..8f2954977a 100644 --- a/src/mbgl/renderer/buckets/fill_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_bucket.hpp @@ -13,10 +13,20 @@ namespace mbgl { class BucketParameters; +class RenderFillLayer; class FillBucket : public Bucket { public: - FillBucket(const BucketParameters&, const std::vector<const RenderLayer*>&); + + // These aliases are used by the PatternLayout template + using RenderLayerType = RenderFillLayer; + using PossiblyEvaluatedPaintProperties = style::FillPaintProperties::PossiblyEvaluated; + using PossiblyEvaluatedLayoutProperties = style::Properties<>::PossiblyEvaluated; + + FillBucket(const PossiblyEvaluatedLayoutProperties layout, + std::map<std::string, PossiblyEvaluatedPaintProperties> layerPaintProperties, + const float zoom, + const uint32_t overscaling); void addFeature(const GeometryTileFeature&, const GeometryCollection&, diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp index fc6e0df5f9..98569d3f74 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.cpp @@ -34,20 +34,25 @@ using namespace style; struct GeometryTooLongException : std::exception {}; -FillExtrusionBucket::FillExtrusionBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) +FillExtrusionBucket::FillExtrusionBucket(const FillExtrusionBucket::PossiblyEvaluatedLayoutProperties, + std::map<std::string, FillExtrusionBucket::PossiblyEvaluatedPaintProperties> layerPaintProperties, + const float zoom, + const uint32_t) : Bucket(LayerType::FillExtrusion) { - for (const auto& layer : layers) { - paintPropertyBinders.emplace(std::piecewise_construct, - std::forward_as_tuple(layer->getID()), - std::forward_as_tuple( - layer->as<RenderFillExtrusionLayer>()->evaluated, - parameters.tileID.overscaledZ)); + + for (const auto& pair : layerPaintProperties) { + paintPropertyBinders.emplace( + std::piecewise_construct, + std::forward_as_tuple(pair.first), + std::forward_as_tuple( + pair.second, + zoom)); } } void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature, const GeometryCollection& geometry, - const ImagePositions&) { + const ImagePositions& patternPositions) { for (auto& polygon : classifyRings(geometry)) { // Optimize polygons with many interior rings for earcut tesselation. limitHoles(polygon, 500); @@ -144,7 +149,7 @@ void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature, } for (auto& pair : paintPropertyBinders) { - pair.second.populateVertexVectors(feature, vertices.vertexSize(), {}); + pair.second.populateVertexVectors(feature, vertices.vertexSize(), patternPositions); } } diff --git a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp index 350723158d..0da69cd749 100644 --- a/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp +++ b/src/mbgl/renderer/buckets/fill_extrusion_bucket.hpp @@ -11,10 +11,20 @@ namespace mbgl { class BucketParameters; +class RenderFillExtrusionLayer; class FillExtrusionBucket : public Bucket { public: - FillExtrusionBucket(const BucketParameters&, const std::vector<const RenderLayer*>&); + + // These aliases are used by the PatternLayout template + using RenderLayerType = RenderFillExtrusionLayer; + using PossiblyEvaluatedPaintProperties = style::FillExtrusionPaintProperties::PossiblyEvaluated; + using PossiblyEvaluatedLayoutProperties = style::Properties<>::PossiblyEvaluated; + + FillExtrusionBucket(const PossiblyEvaluatedLayoutProperties, + std::map<std::string, PossiblyEvaluatedPaintProperties>, + const float, + const uint32_t); void addFeature(const GeometryTileFeature&, const GeometryCollection&, diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index 69be21efd6..eedd565776 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -134,7 +134,9 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome const float miterLimit = joinType == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>()); - const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling)); + const double sharpCornerOffset = overscaling == 0 ? + SHARP_CORNER_OFFSET * (float(util::EXTENT) / util::tileSize) : + SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling)); const GeometryCoordinate firstCoordinate = coordinates[first]; const LineCapType beginCap = layout.get<LineCap>(); diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index 162d168a42..86c4cdbe50 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -17,8 +17,14 @@ class RenderLineLayer; class LineBucket : public Bucket { public: - LineBucket(const style::LineLayoutProperties::PossiblyEvaluated layout, - std::map<std::string, RenderLinePaintProperties::PossiblyEvaluated> layerPaintProperties, + + // These aliases are used by the PatternLayout template + using RenderLayerType = RenderLineLayer; + using PossiblyEvaluatedPaintProperties = RenderLinePaintProperties::PossiblyEvaluated; + using PossiblyEvaluatedLayoutProperties = style::LineLayoutProperties::PossiblyEvaluated; + + LineBucket(const PossiblyEvaluatedLayoutProperties layout, + std::map<std::string, PossiblyEvaluatedPaintProperties> layerPaintProperties, const float zoom, const uint32_t overscaling); @@ -32,7 +38,7 @@ public: float getQueryRadius(const RenderLayer&) const override; - style::LineLayoutProperties::PossiblyEvaluated layout; + PossiblyEvaluatedLayoutProperties layout; gl::VertexVector<LineLayoutVertex> vertices; gl::IndexVector<gl::Triangles> triangles; @@ -43,10 +49,6 @@ public: std::map<std::string, LineProgram::PaintPropertyBinders> paintPropertyBinders; - using RenderLayerType = RenderLineLayer; - using PossiblyEvaluatedPaintProperties = RenderLinePaintProperties::PossiblyEvaluated; - using PossiblyEvaluatedLayoutProperties = style::LineLayoutProperties::PossiblyEvaluated; - private: void addGeometry(const GeometryCoordinates&, const GeometryTileFeature&); diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index cf9d02301a..925a743d66 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -12,6 +12,7 @@ #include <mbgl/geometry/feature_index.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> +#include <mbgl/tile/geometry_tile.hpp> namespace mbgl { @@ -26,8 +27,18 @@ const style::FillExtrusionLayer::Impl& RenderFillExtrusionLayer::impl() const { return static_cast<const style::FillExtrusionLayer::Impl&>(*baseImpl); } -std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const { - return std::make_unique<FillExtrusionBucket>(parameters, layers); +std::unique_ptr<Bucket> RenderFillExtrusionLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const { + assert(false); // Should be calling createLayout() instead. + return nullptr; +} + + +std::unique_ptr<PatternLayout<FillExtrusionBucket>> +RenderFillExtrusionLayer::createLayout(const BucketParameters& parameters, + const std::vector<const RenderLayer*>& group, + std::unique_ptr<GeometryTileLayer> layer, + ImageDependencies& imageDependencies) const { + return std::make_unique<PatternLayout<FillExtrusionBucket>>(parameters, group, std::move(layer), imageDependencies); } void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters) { @@ -36,6 +47,7 @@ void RenderFillExtrusionLayer::transition(const TransitionParameters& parameters void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); + crossfade = parameters.getCrossfadeParameters(); passes = (evaluated.get<style::FillExtrusionOpacity>() > 0) ? (RenderPass::Translucent | RenderPass::Pass3D) @@ -68,8 +80,10 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* parameters.context.setStencilMode(gl::StencilMode::disabled()); parameters.context.clear(Color{ 0.0f, 0.0f, 0.0f, 0.0f }, depthClearValue, {}); - auto draw = [&](auto& programInstance, const auto& tileBucket, auto&& uniformValues) { + auto draw = [&](auto& programInstance, const auto& tileBucket, auto&& uniformValues, + const optional<ImagePosition>& patternPositionA, const optional<ImagePosition>& patternPositionB) { const auto& paintPropertyBinders = tileBucket.paintPropertyBinders.at(getID()); + paintPropertyBinders.setPatternParameters(patternPositionA, patternPositionB, crossfade); const auto allUniformValues = programInstance.computeAllUniformValues( std::move(uniformValues), @@ -97,8 +111,9 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* allAttributeBindings, getID()); }; - - if (evaluated.get<FillExtrusionPattern>().from.empty()) { + const auto fillPattern = evaluated.get<FillExtrusionPattern>(); + const auto fillPatternValue = fillPattern.constantOr(mbgl::Faded<std::basic_string<char> >{ "temp", "temp", 0.0f, 0.0f, 0.0f}); + if (fillPatternValue.from.empty()) { for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillExtrusionBucket>(*baseImpl); if (!bucket_) { @@ -115,26 +130,22 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* parameters.state), parameters.state, parameters.evaluatedLight - ) + ), + {}, {} ); } } else { - optional<ImagePosition> imagePosA = - parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().from); - optional<ImagePosition> imagePosB = - parameters.imageManager.getPattern(evaluated.get<FillExtrusionPattern>().to); - - if (!imagePosA || !imagePosB) { - return; - } - - parameters.imageManager.bind(parameters.context, 0); - for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillExtrusionBucket>(*baseImpl); if (!bucket_) { continue; } + + assert(dynamic_cast<GeometryTile*>(&tile.tile)); + GeometryTile& geometryTile = static_cast<GeometryTile&>(tile.tile); + optional<ImagePosition> patternPosA = geometryTile.getPattern(fillPatternValue.from); + optional<ImagePosition> patternPosB = geometryTile.getPattern(fillPatternValue.to); + parameters.context.bindTexture(*geometryTile.iconAtlasTexture, 0, gl::TextureFilter::Linear); FillExtrusionBucket& bucket = *bucket_; draw( @@ -144,11 +155,16 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* tile.translatedClipMatrix(evaluated.get<FillExtrusionTranslate>(), evaluated.get<FillExtrusionTranslateAnchor>(), parameters.state), - parameters.imageManager.getPixelSize(), *imagePosA, *imagePosB, - evaluated.get<FillExtrusionPattern>(), tile.id, parameters.state, + geometryTile.iconAtlasTexture->size, + crossfade, + tile.id, + parameters.state, -std::pow(2, tile.id.canonical.z) / util::tileSize / 8.0f, + parameters.pixelRatio, parameters.evaluatedLight - ) + ), + patternPosA, + patternPosB ); } } @@ -197,6 +213,17 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* getID()); } } +style::FillExtrusionPaintProperties::PossiblyEvaluated RenderFillExtrusionLayer::paintProperties() const { + return FillExtrusionPaintProperties::PossiblyEvaluated { + evaluated.get<style::FillExtrusionOpacity>(), + evaluated.get<style::FillExtrusionColor>(), + evaluated.get<style::FillExtrusionTranslate>(), + evaluated.get<style::FillExtrusionTranslateAnchor>(), + evaluated.get<style::FillExtrusionPattern>(), + evaluated.get<style::FillExtrusionHeight>(), + evaluated.get<style::FillExtrusionBase>() + }; +} bool RenderFillExtrusionLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp index f7ba13c267..b5ba23649d 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp @@ -8,8 +8,16 @@ namespace mbgl { +template <class B> +class PatternLayout; + +class FillExtrusionBucket; + class RenderFillExtrusionLayer: public RenderLayer { public: + using StyleLayerImpl = style::FillExtrusionLayer::Impl; + using PatternProperty = style::FillExtrusionPattern; + RenderFillExtrusionLayer(Immutable<style::FillExtrusionLayer::Impl>); ~RenderFillExtrusionLayer() final = default; @@ -17,6 +25,7 @@ public: void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; void render(PaintParameters&, RenderSource*) override; + style::FillExtrusionPaintProperties::PossiblyEvaluated paintProperties() const; bool queryIntersectsFeature( const GeometryCoordinates&, @@ -28,6 +37,9 @@ public: std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; + std::unique_ptr<PatternLayout<FillExtrusionBucket>> + createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&, std::unique_ptr<GeometryTileLayer>, ImageDependencies&) const; + // Paint properties style::FillExtrusionPaintProperties::Unevaluated unevaluated; style::FillExtrusionPaintProperties::PossiblyEvaluated evaluated; @@ -35,6 +47,8 @@ public: const style::FillExtrusionLayer::Impl& impl() const; optional<OffscreenTexture> renderTexture; +private: + CrossfadeParameters crossfade; }; template <> diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index 1e46a49d3d..5819c90417 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -10,6 +10,7 @@ #include <mbgl/geometry/feature_index.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> +#include <mbgl/tile/geometry_tile.hpp> namespace mbgl { @@ -24,8 +25,17 @@ const style::FillLayer::Impl& RenderFillLayer::impl() const { return static_cast<const style::FillLayer::Impl&>(*baseImpl); } -std::unique_ptr<Bucket> RenderFillLayer::createBucket(const BucketParameters& parameters, const std::vector<const RenderLayer*>& layers) const { - return std::make_unique<FillBucket>(parameters, layers); +std::unique_ptr<Bucket> RenderFillLayer::createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const { + assert(false); // Should be calling createLayout() instead. + return nullptr; +} + +std::unique_ptr<PatternLayout<FillBucket>> +RenderFillLayer::createLayout(const BucketParameters& parameters, + const std::vector<const RenderLayer*>& group, + std::unique_ptr<GeometryTileLayer> layer, + ImageDependencies& imageDependencies) const { + return std::make_unique<PatternLayout<FillBucket>>(parameters, group, std::move(layer), imageDependencies); } void RenderFillLayer::transition(const TransitionParameters& parameters) { @@ -34,6 +44,7 @@ void RenderFillLayer::transition(const TransitionParameters& parameters) { void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) { evaluated = unevaluated.evaluate(parameters); + crossfade = parameters.getCrossfadeParameters(); if (unevaluated.get<style::FillOutlineColor>().isUndefined()) { evaluated.get<style::FillOutlineColor>() = evaluated.get<style::FillColor>(); @@ -59,7 +70,9 @@ bool RenderFillLayer::hasTransition() const { } void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { - if (evaluated.get<FillPattern>().from.empty()) { + const auto fillPattern = evaluated.get<FillPattern>(); + const auto fillPatternValue = fillPattern.constantOr(mbgl::Faded<std::basic_string<char> >{ "temp", "temp", 0.0f, 0.0f, 0.0f}); + if (fillPatternValue.from.empty()) { for (const RenderTile& tile : renderTiles) { auto bucket_ = tile.tile.getBucket<FillBucket>(*baseImpl); if (!bucket_) { @@ -139,16 +152,13 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { return; } - optional<ImagePosition> imagePosA = parameters.imageManager.getPattern(evaluated.get<FillPattern>().from); - optional<ImagePosition> imagePosB = parameters.imageManager.getPattern(evaluated.get<FillPattern>().to); - - if (!imagePosA || !imagePosB) { - return; - } - - parameters.imageManager.bind(parameters.context, 0); - for (const RenderTile& tile : renderTiles) { + assert(dynamic_cast<GeometryTile*>(&tile.tile)); + GeometryTile& geometryTile = static_cast<GeometryTile&>(tile.tile); + optional<ImagePosition> patternPosA = geometryTile.getPattern(fillPatternValue.from); + optional<ImagePosition> patternPosB = geometryTile.getPattern(fillPatternValue.to); + + parameters.context.bindTexture(*geometryTile.iconAtlasTexture, 0, gl::TextureFilter::Linear); auto bucket_ = tile.tile.getBucket<FillBucket>(*baseImpl); if (!bucket_) { continue; @@ -163,6 +173,7 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { auto& programInstance = program.get(evaluated); const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID()); + paintPropertyBinders.setPatternParameters(patternPosA, patternPosB, crossfade); const auto allUniformValues = programInstance.computeAllUniformValues( FillPatternUniforms::values( @@ -170,12 +181,11 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { evaluated.get<FillTranslateAnchor>(), parameters.state), parameters.context.viewport.getCurrentValue().size, - parameters.imageManager.getPixelSize(), - *imagePosA, - *imagePosB, - evaluated.get<FillPattern>(), + geometryTile.iconAtlasTexture->size, + crossfade, tile.id, - parameters.state + parameters.state, + parameters.pixelRatio ), paintPropertyBinders, evaluated, @@ -220,6 +230,18 @@ void RenderFillLayer::render(PaintParameters& parameters, RenderSource*) { } } +style::FillPaintProperties::PossiblyEvaluated RenderFillLayer::paintProperties() const { + return FillPaintProperties::PossiblyEvaluated { + evaluated.get<style::FillAntialias>(), + evaluated.get<style::FillOpacity>(), + evaluated.get<style::FillColor>(), + evaluated.get<style::FillOutlineColor>(), + evaluated.get<style::FillTranslate>(), + evaluated.get<style::FillTranslateAnchor>(), + evaluated.get<style::FillPattern>() + }; +} + bool RenderFillLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, diff --git a/src/mbgl/renderer/layers/render_fill_layer.hpp b/src/mbgl/renderer/layers/render_fill_layer.hpp index bd195fb828..3403262121 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_layer.hpp @@ -3,11 +3,17 @@ #include <mbgl/renderer/render_layer.hpp> #include <mbgl/style/layers/fill_layer_impl.hpp> #include <mbgl/style/layers/fill_layer_properties.hpp> +#include <mbgl/layout/pattern_layout.hpp> namespace mbgl { +class FillBucket; + class RenderFillLayer: public RenderLayer { public: + using StyleLayerImpl = style::FillLayer::Impl; + using PatternProperty = style::FillPattern; + RenderFillLayer(Immutable<style::FillLayer::Impl>); ~RenderFillLayer() final = default; @@ -15,6 +21,7 @@ public: void evaluate(const PropertyEvaluationParameters&) override; bool hasTransition() const override; void render(PaintParameters&, RenderSource*) override; + style::FillPaintProperties::PossiblyEvaluated paintProperties() const; bool queryIntersectsFeature( const GeometryCoordinates&, @@ -26,11 +33,17 @@ public: std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; + std::unique_ptr<PatternLayout<FillBucket>> + createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&, std::unique_ptr<GeometryTileLayer>, ImageDependencies&) const; + // Paint properties style::FillPaintProperties::Unevaluated unevaluated; style::FillPaintProperties::PossiblyEvaluated evaluated; const style::FillLayer::Impl& impl() const; +private: + CrossfadeParameters crossfade; + }; template <> diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index a50ecdc3ff..cd134fb7da 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -32,14 +32,12 @@ std::unique_ptr<Bucket> RenderLineLayer::createBucket(const BucketParameters&, c return nullptr; } -std::unique_ptr<PatternLayout<LineBucket, RenderLineLayer>> RenderLineLayer::createLayout(const BucketParameters& parameters, - const std::vector<const RenderLayer*>& group, - std::unique_ptr<GeometryTileLayer> layer, - ImageDependencies& imageDependencies) const { - return std::make_unique<PatternLayout<LineBucket, RenderLineLayer>>(parameters, - group, - std::move(layer), - imageDependencies); +std::unique_ptr<PatternLayout<LineBucket>> +RenderLineLayer::createLayout(const BucketParameters& parameters, + const std::vector<const RenderLayer*>& group, + std::unique_ptr<GeometryTileLayer> layer, + ImageDependencies& imageDependencies) const { + return std::make_unique<PatternLayout<LineBucket>>(parameters, group, std::move(layer), imageDependencies); } void RenderLineLayer::transition(const TransitionParameters& parameters) { @@ -114,11 +112,10 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { ); }; const auto linepattern = evaluated.get<LinePattern>(); - // TODO get real crossfade parameters + // need a non-empty placeholder value that will result in the LinePattern program to be // used if the line-pattern value is non-constant const auto linePatternValue = linepattern.constantOr(mbgl::Faded<std::basic_string<char> >{ "temp", "temp", 0.0f, 0.0f, 0.0f}); - if (!evaluated.get<LineDasharray>().from.empty()) { const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round ? LinePatternCap::Round : LinePatternCap::Square; diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp index e2eb6ebed9..52d307e5a5 100644 --- a/src/mbgl/renderer/layers/render_line_layer.hpp +++ b/src/mbgl/renderer/layers/render_line_layer.hpp @@ -21,6 +21,9 @@ class LineBucket; class RenderLineLayer: public RenderLayer { public: + using StyleLayerImpl = style::LineLayer::Impl; + using PatternProperty = style::LinePattern; + RenderLineLayer(Immutable<style::LineLayer::Impl>); ~RenderLineLayer() final = default; @@ -42,7 +45,7 @@ public: void updateColorRamp(); std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; - std::unique_ptr<PatternLayout<LineBucket, RenderLineLayer>> createLayout(const BucketParameters&, + std::unique_ptr<PatternLayout<LineBucket>> createLayout(const BucketParameters&, const std::vector<const RenderLayer*>&, std::unique_ptr<GeometryTileLayer>, ImageDependencies&) const; @@ -50,8 +53,7 @@ public: style::LinePaintProperties::Unevaluated unevaluated; RenderLinePaintProperties::PossiblyEvaluated evaluated; - using StyleLayerImpl = style::LineLayer::Impl; - using PatternProperty = style::LinePattern; + const style::LineLayer::Impl& impl() const; private: diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index cf3f9716df..e2802671b5 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -10,6 +10,7 @@ #include <mbgl/renderer/cross_faded_property_evaluator.hpp> #include <mbgl/util/variant.hpp> #include <mbgl/renderer/image_atlas.hpp> +#include <mbgl/util/indexed_tuple.hpp> #include <bitset> @@ -139,8 +140,9 @@ public: } } - std::tuple<optional<gl::AttributeBinding>, optional<gl::AttributeBinding>> attributeBinding(const PossiblyEvaluatedPropertyValue<Faded<T>>&) const override { - return std::tuple<ExpandToType<As, optional<gl::AttributeBinding>>...> {}; + std::tuple<optional<gl::AttributeBinding>, optional<gl::AttributeBinding>> + attributeBinding(const PossiblyEvaluatedPropertyValue<Faded<T>>&) const override { + return std::tuple<optional<gl::AttributeBinding>, optional<gl::AttributeBinding>> {}; } std::tuple<float, float> interpolationFactor(float) const override { diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp index 9abc6fc4b3..9a9a52dea4 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp @@ -14,6 +14,7 @@ public: bool hasLayoutDifference(const Layer::Impl&) const override; void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override; + Properties<>::Unevaluated layout; FillExtrusionPaintProperties::Transitionable paint; }; diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp index 2673cd7443..22573e0d5d 100644 --- a/src/mbgl/style/layers/fill_layer_impl.hpp +++ b/src/mbgl/style/layers/fill_layer_impl.hpp @@ -14,6 +14,7 @@ public: bool hasLayoutDifference(const Layer::Impl&) const override; void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override; + Properties<>::Unevaluated layout; FillPaintProperties::Transitionable paint; }; diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index f017f1f0ef..463150e59b 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -7,9 +7,11 @@ #include <mbgl/renderer/group_by_layout.hpp> #include <mbgl/style/filter.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> +#include <mbgl/renderer/layers/render_fill_layer.hpp> +#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp> +#include <mbgl/renderer/layers/render_line_layer.hpp> #include <mbgl/renderer/layers/render_symbol_layer.hpp> #include <mbgl/renderer/buckets/symbol_bucket.hpp> -#include <mbgl/renderer/buckets/line_bucket.hpp> #include <mbgl/util/logging.hpp> #include <mbgl/util/constants.hpp> #include <mbgl/util/string.hpp> @@ -197,11 +199,15 @@ void GeometryTileWorker::symbolDependenciesChanged() { assert(hasPendingParseResult()); performSymbolLayout(); coalesce(); + } else if (patternNeedsLayout) { + performSymbolLayout(); + coalesce(); } + break; case Coalescing: - if (symbolLayoutsNeedPreparation) { + if (symbolLayoutsNeedPreparation || patternNeedsLayout) { state = NeedsSymbolLayout; } break; @@ -334,13 +340,13 @@ void GeometryTileWorker::parse() { std::vector<std::string> patternOrder; for (auto it = layers->rbegin(); it != layers->rend(); it++) { - if ((*it)->type == LayerType::Line) { + if ((*it)->type == LayerType::Line || (*it)->type == LayerType::Fill || (*it)->type == LayerType::FillExtrusion) { patternOrder.push_back((*it)->id); } } std::unordered_map<std::string, std::unique_ptr<SymbolLayout>> symbolLayoutMap; - std::unordered_map<std::string, std::unique_ptr<PatternLayout<LineBucket, RenderLineLayer>>> patternLayoutMap; + std::unordered_map<std::string, variant<std::unique_ptr<LinePatternLayout>, std::unique_ptr<FillPatternLayout>, std::unique_ptr<FillExtrusionPatternLayout>>> patternLayoutMap; buckets.clear(); featureIndex = std::make_unique<FeatureIndex>(*data ? (*data)->clone() : nullptr); @@ -382,10 +388,20 @@ void GeometryTileWorker::parse() { symbolLayoutMap.emplace(leader.getID(), std::move(layout)); symbolLayoutsNeedPreparation = true; } else if (leader.is<RenderLineLayer>()) { - auto layout = leader.as<RenderLineLayer>()->createLayout( + std::unique_ptr<PatternLayout<LineBucket>> layout = leader.as<RenderLineLayer>()->createLayout( parameters, group, std::move(geometryLayer), imageDependencies); patternLayoutMap.emplace(leader.getID(), std::move(layout)); - symbolLayoutsNeedPreparation = true; + patternNeedsLayout = true; + } else if (leader.is<RenderFillLayer>()) { + std::unique_ptr<PatternLayout<FillBucket>> layout = leader.as<RenderFillLayer>()->createLayout( + parameters, group, std::move(geometryLayer), imageDependencies); + patternLayoutMap.emplace(leader.getID(), std::move(layout)); + patternNeedsLayout = true; + } else if (leader.is<RenderFillExtrusionLayer>()) { + std::unique_ptr<PatternLayout<FillExtrusionBucket>> layout = leader.as<RenderFillExtrusionLayer>()->createLayout( + parameters, group, std::move(geometryLayer), imageDependencies); + patternLayoutMap.emplace(leader.getID(), std::move(layout)); + patternNeedsLayout = true; } else { const Filter& filter = leader.baseImpl->filter; const std::string& sourceLayerID = leader.baseImpl->sourceLayer; @@ -483,16 +499,33 @@ void GeometryTileWorker::performSymbolLayout() { iconAtlas = makeImageAtlas(imageMap, patternMap); } - for (auto& patternLayout : patternLayouts) { + for (auto& value : patternLayouts) { if (obsolete) { return; } - std::shared_ptr<LineBucket> bucket = patternLayout->createBucket(iconAtlas.patternPositions, featureIndex); - for (const auto& pair : patternLayout->layerPaintProperties) { - buckets.emplace(pair.first, bucket); - } + value.match( + [&] (const std::unique_ptr<PatternLayout<LineBucket>>& linePatternLayout) { + std::shared_ptr<LineBucket> bucket = linePatternLayout->createBucket(iconAtlas.patternPositions, featureIndex); + for (const auto& pair : linePatternLayout->layerPaintProperties) { + buckets.emplace(pair.first, bucket); + } + }, + [&] (const std::unique_ptr<PatternLayout<FillBucket>>& fillPatternLayout) { + std::shared_ptr<FillBucket> bucket = fillPatternLayout->createBucket(iconAtlas.patternPositions, featureIndex); + for (const auto& pair : fillPatternLayout->layerPaintProperties) { + buckets.emplace(pair.first, bucket); + } + }, + [&] (const std::unique_ptr<PatternLayout<FillExtrusionBucket>>& fillExtrusionLayout) { + std::shared_ptr<FillExtrusionBucket> bucket = fillExtrusionLayout->createBucket(iconAtlas.patternPositions, featureIndex); + for (const auto& pair : fillExtrusionLayout->layerPaintProperties) { + buckets.emplace(pair.first, bucket); + } + } + ); } + patternNeedsLayout = false; for (auto& symbolLayout : symbolLayouts) { if (obsolete) { diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp index 440d4d7162..3f0d435a47 100644 --- a/src/mbgl/tile/geometry_tile_worker.hpp +++ b/src/mbgl/tile/geometry_tile_worker.hpp @@ -10,6 +10,9 @@ #include <mbgl/style/layer_impl.hpp> #include <mbgl/geometry/feature_index.hpp> #include <mbgl/renderer/bucket.hpp> +#include <mbgl/renderer/buckets/fill_bucket.hpp> +#include <mbgl/renderer/buckets/fill_extrusion_bucket.hpp> +#include <mbgl/renderer/buckets/line_bucket.hpp> #include <atomic> #include <memory> @@ -20,12 +23,9 @@ class GeometryTile; class GeometryTileData; class SymbolLayout; -template <class B, class L> +template <class B> class PatternLayout; -class RenderLineLayer; -class LineBucket; - namespace style { class Layer; } // namespace style @@ -91,9 +91,15 @@ private: optional<std::unique_ptr<const GeometryTileData>> data; bool symbolLayoutsNeedPreparation = false; + bool patternNeedsLayout = false; std::vector<std::unique_ptr<SymbolLayout>> symbolLayouts; - std::vector<std::unique_ptr<PatternLayout<LineBucket, RenderLineLayer>>> patternLayouts; + + using LinePatternLayout = PatternLayout<LineBucket>; + using FillPatternLayout = PatternLayout<FillBucket>; + using FillExtrusionPatternLayout = PatternLayout<FillExtrusionBucket>; + + std::vector<variant<std::unique_ptr<LinePatternLayout>, std::unique_ptr<FillPatternLayout>, std::unique_ptr<FillExtrusionPatternLayout>>> patternLayouts; GlyphDependencies pendingGlyphDependencies; ImageDependencies pendingImageDependencies; diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index bc7518fb33..c5be975ee5 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -64,9 +64,10 @@ TEST(Buckets, CircleBucket) { TEST(Buckets, FillBucket) { HeadlessBackend backend({ 512, 256 }); BackendScope scope { backend }; + style::Properties<>::PossiblyEvaluated layout; gl::Context context; - FillBucket bucket { { {0, 0, 0}, MapMode::Static, 1.0 }, {} }; + FillBucket bucket { layout, {}, 5.0f, 1}; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); @@ -85,7 +86,7 @@ TEST(Buckets, LineBucket) { style::LineLayoutProperties::PossiblyEvaluated layout; gl::Context context; - LineBucket bucket { layout, {}, 10.0f, 0 }; + LineBucket bucket { layout, {}, 10.0f, 1 }; ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); |