Skip to content

Commit

Permalink
Custom drawable layer v2 (#1754)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefankarschti authored Oct 26, 2023
1 parent 619408d commit 40e283c
Show file tree
Hide file tree
Showing 26 changed files with 670 additions and 225 deletions.
3 changes: 2 additions & 1 deletion include/mbgl/gfx/drawable_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,10 @@ class DrawableBuilder {
/// Add a polyline. If the last point equals the first it will be closed, otherwise open
void addPolyline(const GeometryCoordinates& coordinates, const gfx::PolylineGeneratorOptions&);

protected:
/// return the curent vertex count
std::size_t curVertexCount() const;

protected:
/// Create an instance of the appropriate drawable type
virtual UniqueDrawable createDrawable() const = 0;

Expand Down
7 changes: 4 additions & 3 deletions include/mbgl/gfx/polyline_generator.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <mbgl/util/geometry.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/gfx/vertex_vector.hpp>
Expand Down Expand Up @@ -40,8 +41,8 @@ struct PolylineGeneratorOptions {
style::LineCapType beginCap{style::LineCapType::Butt};
style::LineCapType endCap{style::LineCapType::Butt};
float roundLimit{1.f};
uint32_t overscaling{1}; // TODO: what is this???
std::optional<PolylineGeneratorDistances> lineDistances;
uint32_t overscaling{1};
std::optional<PolylineGeneratorDistances> clipDistances;
};

template <class PolylineLayoutVertex, class PolylineSegment>
Expand Down Expand Up @@ -100,4 +101,4 @@ class PolylineGenerator {
};

} // namespace gfx
} // namespace mbgl
} // namespace mbgl
91 changes: 84 additions & 7 deletions include/mbgl/style/layers/custom_drawable_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,107 @@
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/renderer/change_request.hpp>
#include <mbgl/gfx/drawable_builder.hpp>

#include <array>
#include <memory>
#include <optional>

namespace mbgl {
namespace style {

class CustomDrawableLayerHost {
public:
class Interface;

public:
virtual ~CustomDrawableLayerHost() = default;

virtual void initialize() = 0;

virtual void update(RenderLayer& proxyLayer,
gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>&,
const RenderTree& renderTree,
UniqueChangeRequestVec& changes) = 0;
virtual void update(Interface& interface) = 0;

virtual void deinitialize() = 0;
};

class CustomDrawableLayerHost::Interface {
public:
struct LineOptions {
Color color;
float blur = 0.f;
float opacity = 1.f;
float gapWidth = 0.f;
float offset = 0.f;
float width = 1.f;
gfx::PolylineGeneratorOptions geometry;
};

public:
/// @brief Construct a new Interface object (internal core use only)
Interface(RenderLayer& layer,
LayerGroupBasePtr& layerGroup,
gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& state,
const std::shared_ptr<UpdateParameters>& updateParameters,
const RenderTree& renderTree,
UniqueChangeRequestVec& changes);
/**
* @brief Get the drawable count
*
* @return std::size_t
*/
std::size_t getDrawableCount() const;

/**
* @brief Set the Tile ID
*
* @param tileID
*/
void setTileID(OverscaledTileID tileID);

/**
* @brief Set the line options
*
* @param options
*/
void setLineOptions(const LineOptions& options);

/**
* @brief Add a polyline
*
* @param coordinates
* @param options Polyline options
*/
void addPolyline(const GeometryCoordinates& coordinates);

/**
* @brief Finishe the current drawable building session
*
*/
void finish();

protected:
gfx::ShaderPtr lineShaderDefault() const;

std::unique_ptr<gfx::DrawableBuilder> createBuilder(const std::string& name, gfx::ShaderPtr shader) const;

public:
RenderLayer& layer;
LayerGroupBasePtr& layerGroup;
gfx::ShaderRegistry& shaders;
gfx::Context& context;
const TransformState& state;
const std::shared_ptr<UpdateParameters>& updateParameters;
const RenderTree& renderTree;
UniqueChangeRequestVec& changes;

private:
std::unique_ptr<gfx::DrawableBuilder> builder;
std::optional<OverscaledTileID> tileID;
LineOptions lineOptions;
};

class CustomDrawableLayer final : public Layer {
public:
CustomDrawableLayer(const std::string& id, std::unique_ptr<CustomDrawableLayerHost> host);
Expand Down
2 changes: 1 addition & 1 deletion include/mbgl/util/feature.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#pragma once

#include <mbgl/util/string.hpp>

#include <mapbox/compatibility/value.hpp>

#include <optional>
#include <unordered_map>

namespace mbgl {

Expand Down
40 changes: 38 additions & 2 deletions platform/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ objc_library(
"//conditions:default": [
"//platform/darwin:darwin_objcpp_opengl_srcs",
],
}) + select({
"//:legacy_renderer": [],
"//conditions:default": [
"//platform/darwin:darwin_objcpp_custom_drawable_srcs",
],
}),
copts = CPP_FLAGS + MAPLIBRE_FLAGS + [
"-fcxx-modules",
Expand Down Expand Up @@ -165,6 +170,28 @@ objc_library(
],
)

objc_library(
name = "app_custom_drawable_layer_objcpp_srcs",
srcs = [
"//platform/darwin:app/ExampleCustomDrawableStyleLayer.h",
"//platform/darwin:app/ExampleCustomDrawableStyleLayer.mm",
],
copts = CPP_FLAGS + MAPLIBRE_FLAGS + WARNING_FLAGS["ios"] + [
"-fcxx-modules",
"-fmodules",
"-Wno-c99-extensions",
"-Wno-gnu-zero-variadic-macro-arguments",
"-Wno-gnu-conditional-omitted-operand",
"-Wno-gnu-statement-expression",
"-Wno-deprecated-declarations",
],
visibility = ["//visibility:public"],
deps = [
"//:mbgl-core",
":ios-sdk",
],
)

objc_library(
name = "iosapp",
srcs = [
Expand All @@ -183,7 +210,6 @@ objc_library(
includes = [
"darwin/app",
"darwin/src",
"ios/src",
],
sdk_frameworks = [
] + select({
Expand All @@ -196,7 +222,12 @@ objc_library(
visibility = ["//visibility:public"],
deps = [
":ios-sdk",
],
] + select({
"//:legacy_renderer": [],
"//conditions:default": [
":app_custom_drawable_layer_objcpp_srcs",
],
}),
)

objc_library(
Expand Down Expand Up @@ -242,6 +273,11 @@ sh_binary(
"//conditions:default": [
"//platform/darwin:darwin_objcpp_opengl_srcs",
],
}) + select({
"//:legacy_renderer": [],
"//conditions:default": [
"//platform/darwin:darwin_objcpp_custom_drawable_srcs",
],
}),
deps = [
"//platform/darwin:generated_code",
Expand Down
10 changes: 10 additions & 0 deletions platform/darwin/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ load(
"MLN_DARWIN_PRIVATE_HEADERS",
"MLN_DARWIN_PUBLIC_OBJCPP_SOURCE",
"MLN_DARWIN_PUBLIC_OBJCPP_OPENGL_SOURCE",
"MLN_DARWIN_PUBLIC_OBJCPP_CUSTOM_DRAWABLE_SOURCE",
"MLN_DARWIN_PUBLIC_OBJC_SOURCE",
"MLN_GENERATED_DARWIN_STYLE_HEADERS",
"MLN_GENERATED_DARWIN_STYLE_PUBLIC_HEADERS",
Expand Down Expand Up @@ -47,6 +48,12 @@ filegroup(
visibility = ["//visibility:public"],
)

filegroup(
name = "darwin_objcpp_custom_drawable_srcs",
srcs = MLN_DARWIN_PUBLIC_OBJCPP_CUSTOM_DRAWABLE_SOURCE,
visibility = ["//visibility:public"],
)

filegroup(
name = "darwin_objc_srcs",
srcs = MLN_DARWIN_PUBLIC_OBJC_SOURCE,
Expand Down Expand Up @@ -324,12 +331,15 @@ exports_files(
"test/MLNSDKTestHelpers.swift",
"app/LimeGreenStyleLayer.h",
"app/LimeGreenStyleLayer.m",
"app/ExampleCustomDrawableStyleLayer.h",
"app/ExampleCustomDrawableStyleLayer.mm",
"include/mbgl/util/image+MLNAdditions.hpp",
"scripts/check-public-symbols.js",
"scripts/check-public-symbols.sh",
] + MLN_DARWIN_PUBLIC_OBJC_SOURCE +
MLN_DARWIN_PUBLIC_OBJCPP_SOURCE +
MLN_DARWIN_PUBLIC_OBJCPP_OPENGL_SOURCE +
MLN_DARWIN_PUBLIC_OBJCPP_CUSTOM_DRAWABLE_SOURCE +
MLN_DARWIN_PRIVATE_HEADERS +
MLN_DARWIN_OBJC_HEADERS +
MLN_DARWIN_OBJCPP_HEADERS,
Expand Down
12 changes: 12 additions & 0 deletions platform/darwin/app/ExampleCustomDrawableStyleLayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#import "Mapbox.h"

#import "MLNFoundation.h"
#import "MLNStyleValue.h"
#import "MLNStyleLayer.h"
#import "MLNGeometry.h"

@interface ExampleCustomDrawableStyleLayer : MLNStyleLayer

- (instancetype)initWithIdentifier:(NSString *)identifier;

@end
100 changes: 100 additions & 0 deletions platform/darwin/app/ExampleCustomDrawableStyleLayer.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#import "ExampleCustomDrawableStyleLayer.h"
#import "MLNStyleLayer.h"

#import "MLNCustomDrawableStyleLayer_Private.h"
#import "MLNStyle_Private.h"
#import "MLNStyleLayer_Private.h"
#import "MLNGeometry_Private.h"

#include <mbgl/layermanager/layer_factory.hpp>
#include <mbgl/style/layer.hpp>
#include <mbgl/style/layers/custom_drawable_layer.hpp>
#include <mbgl/util/constants.hpp>

#include <memory>
#include <cmath>

class ExampleCustomDrawableStyleLayerHost;

@implementation ExampleCustomDrawableStyleLayer

- (instancetype)initWithIdentifier:(NSString *)identifier {
auto layer = std::make_unique<mbgl::style::CustomDrawableLayer>(identifier.UTF8String,
std::make_unique<ExampleCustomDrawableStyleLayerHost>(self));
return self = [super initWithPendingLayer:std::move(layer)];
}


@end

class ExampleCustomDrawableStyleLayerHost : public mbgl::style::CustomDrawableLayerHost {
public:
ExampleCustomDrawableStyleLayerHost(ExampleCustomDrawableStyleLayer *styleLayer) {
layerRef = styleLayer;
layer = nil;
}

void initialize() override {
if (layerRef == nil) return;
else if (layer == nil) layer = layerRef;
}

void update(Interface& interface) override {

// if we have built our drawable(s) already, either update or skip
if (interface.getDrawableCount())
return;

// set tile
interface.setTileID({11, 327, 791});

// add polylines
using namespace mbgl;

constexpr auto numLines = 6;
Interface::LineOptions options[numLines] {
{/*color=*/Color::red(), /*blur=*/0.0f, /*opacity=*/1.0f, /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/8.0f, {} },
{/*color=*/Color::blue(), /*blur=*/4.0f, /*opacity=*/1.0f, /*gapWidth=*/2.0f, /*offset=*/-1.0f, /*width=*/4.0f, {} },
{/*color=*/Color(1.f, 0.5f, 0, 0.5f), /*blur=*/16.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/2.0f, /*width=*/16.0f, {} },
{/*color=*/Color(1.f, 1.f, 0, 0.3f), /*blur=*/2.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/-2.0f, /*width=*/2.0f, {} },
{/*color=*/Color::black(), /*blur=*/0.5f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/0.5f, /*width=*/0.5f, {} },
{/*color=*/Color(1.f, 0, 1.f, 0.2f), /*blur=*/24.0f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/-5.0f, /*width=*/24.0f, {} },
};
for(auto& opt: options) {
opt.geometry.beginCap = style::LineCapType::Round;
opt.geometry.endCap = style::LineCapType::Round;
opt.geometry.joinType = style::LineJoinType::Round;
}

constexpr auto numPoints = 100;
GeometryCoordinates polyline;
for (auto ipoint{0}; ipoint < numPoints; ++ipoint) {
polyline.emplace_back(ipoint * util::EXTENT / numPoints, std::sin(ipoint * 2 * M_PI / numPoints) * util::EXTENT / numLines / 2.f);
}

for (auto index {0}; index < numLines; ++index) {
for(auto &p : polyline) {
p.y += util::EXTENT / numLines;
}

// set property values
interface.setLineOptions(options[index]);

// add polyline
interface.addPolyline(polyline);
}

// finish
interface.finish();
}

void deinitialize() override {
if (layer == nil) return;

layerRef = layer;
layer = nil;
}
private:
__weak ExampleCustomDrawableStyleLayer * layerRef;
ExampleCustomDrawableStyleLayer * layer = nil;
};
Loading

0 comments on commit 40e283c

Please sign in to comment.