summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2015-12-09 16:52:59 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-12-11 12:44:54 -0800
commit65b3220368f669dd7ddbcb06e95019319e0c536a (patch)
treef0e5a437f11feb231336dc7aa4ce67fd07ebab92
parent78691fa9e61dadbb73be28bcac1a606d7a029ad4 (diff)
downloadqtlocation-mapboxgl-65b3220368f669dd7ddbcb06e95019319e0c536a.tar.gz
[core] Reduce custom layer API to lowest common denominator
-rw-r--r--include/mbgl/map/map.hpp11
-rw-r--r--include/mbgl/style/types.hpp39
-rw-r--r--src/mbgl/layer/custom_layer.cpp49
-rw-r--r--src/mbgl/layer/custom_layer.hpp46
-rw-r--r--src/mbgl/map/map.cpp16
-rw-r--r--src/mbgl/renderer/painter.cpp2
-rw-r--r--test/api/custom_layer.cpp25
7 files changed, 139 insertions, 49 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index 8057837546..df7597ced4 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -9,6 +9,7 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/vec.hpp>
#include <mbgl/annotation/annotation.hpp>
+#include <mbgl/style/types.hpp>
#include <cstdint>
#include <string>
@@ -27,7 +28,6 @@ class Transform;
class PointAnnotation;
class ShapeAnnotation;
struct CameraOptions;
-class StyleLayer;
namespace util {
template <class T> class Thread;
@@ -164,9 +164,12 @@ public:
AnnotationIDs getPointAnnotationsInBounds(const LatLngBounds&);
LatLngBounds getBoundsForAnnotations(const AnnotationIDs&);
- // Style API
- void addLayer(std::unique_ptr<StyleLayer>);
- void addLayer(std::unique_ptr<StyleLayer>, const std::string& before);
+ void addCustomLayer(const std::string& id,
+ CustomLayerInitializeFunction,
+ CustomLayerRenderFunction,
+ CustomLayerDeinitializeFunction,
+ void* context,
+ const char* before = nullptr);
// Memory
void setSourceTileCacheSize(size_t);
diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp
index 95944ce18f..38915db7d8 100644
--- a/include/mbgl/style/types.hpp
+++ b/include/mbgl/style/types.hpp
@@ -189,6 +189,45 @@ MBGL_DEFINE_ENUM_CLASS(TextTransformTypeClass, TextTransformType, {
{ TextTransformType::Lowercase, "lowercase" },
});
+/**
+ * Initialize any GL state needed by the custom layer. This method is called once, from the
+ * rendering thread, at a point when the GL context is active but before rendering for the
+ * first time.
+ *
+ * Resources that are acquired in this method must be released in the UninitializeFunction.
+ */
+using CustomLayerInitializeFunction = void (*)(void* context);
+
+/**
+ * Parameters that define the current camera position for a CustomLayerRenderFunction.
+ */
+struct CustomLayerRenderParameters {
+ double width;
+ double height;
+ double latitude;
+ double longitude;
+ double zoom;
+ double bearing;
+ double pitch;
+ double altitude;
+};
+
+/**
+ * Render the layer. This method is called once per frame. The implementation should not make
+ * any assumptions about the GL state (other than that the correct context is active). It may
+ * make changes to the state, and is not required to reset values such as the depth mask, stencil
+ * mask, and corresponding test flags to their original values.
+ */
+using CustomLayerRenderFunction = void (*)(void* context, const CustomLayerRenderParameters&);
+
+/**
+ * Destroy any GL state needed by the custom layer, and deallocate context, if necessary. This
+ * method is called once, from the rendering thread, at a point when the GL context is active.
+ *
+ * Note that it may be called even when the InitializeFunction has not been called.
+ */
+using CustomLayerDeinitializeFunction = void (*)(void* context);
+
} // namespace mbgl
#endif
diff --git a/src/mbgl/layer/custom_layer.cpp b/src/mbgl/layer/custom_layer.cpp
index 1a47193525..39742ecad8 100644
--- a/src/mbgl/layer/custom_layer.cpp
+++ b/src/mbgl/layer/custom_layer.cpp
@@ -1,10 +1,53 @@
#include <mbgl/layer/custom_layer.hpp>
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/map/transform_state.hpp>
namespace mbgl {
-CustomLayer::CustomLayer(const std::string& id_) {
+CustomLayer::CustomLayer(const std::string& id_,
+ CustomLayerInitializeFunction initializeFn_,
+ CustomLayerRenderFunction renderFn_,
+ CustomLayerDeinitializeFunction deinitializeFn_,
+ void * context_) {
id = id_;
+ initializeFn = initializeFn_;
+ renderFn = renderFn_;
+ deinitializeFn = deinitializeFn_;
+ context = context_;
+}
+
+CustomLayer::CustomLayer(const CustomLayer& other)
+ : StyleLayer(other) {
+ id = other.id;
+ // Don't copy anything else.
+}
+
+CustomLayer::~CustomLayer() {
+ if (deinitializeFn) {
+ deinitializeFn(context);
+ }
+}
+
+void CustomLayer::initialize() {
+ assert(initializeFn);
+ initializeFn(context);
+}
+
+void CustomLayer::render(const TransformState& state) const {
+ assert(renderFn);
+
+ CustomLayerRenderParameters parameters;
+
+ parameters.width = state.getWidth();
+ parameters.height = state.getHeight();
+ parameters.latitude = state.getLatLng().latitude;
+ parameters.longitude = state.getLatLng().longitude;
+ parameters.zoom = state.getZoom();
+ parameters.bearing = -state.getAngle() / M_PI * 180;
+ parameters.pitch = state.getPitch();
+ parameters.altitude = state.getAltitude();
+
+ renderFn(context, parameters);
}
bool CustomLayer::recalculate(const StyleCalculationParameters&) {
@@ -12,6 +55,10 @@ bool CustomLayer::recalculate(const StyleCalculationParameters&) {
return false;
}
+std::unique_ptr<StyleLayer> CustomLayer::clone() const {
+ return std::make_unique<CustomLayer>(*this);
+}
+
std::unique_ptr<Bucket> CustomLayer::createBucket(StyleBucketParameters&) const {
return nullptr;
}
diff --git a/src/mbgl/layer/custom_layer.hpp b/src/mbgl/layer/custom_layer.hpp
index 172eed3051..efdc5f397b 100644
--- a/src/mbgl/layer/custom_layer.hpp
+++ b/src/mbgl/layer/custom_layer.hpp
@@ -5,35 +5,24 @@
namespace mbgl {
-class StyleRenderParameters;
+class TransformState;
class CustomLayer : public StyleLayer {
public:
- CustomLayer(const std::string& id);
- CustomLayer(const CustomLayer&) = default;
-
- /**
- * Initialize any GL state needed by the custom layer. This method is called once, from the
- * rendering thread, at a point when the GL context is active but before rendering for the
- * first time.
- *
- * Resources that are acquired in this method must be released in the subclass's destructor.
- * However, note that in some situations the destructor may be called without initialize()
- * having been called. The destructor should be prepared for this case, e.g. by checking if
- * the resources were actually acquired before releasing them.
- */
- virtual void initialize() = 0;
-
- /**
- * Render the layer. This method is called once per frame. The implementation should not make
- * any assumptions about the GL state (other than that the correct context is active). It may
- * make changes to the state, and is not required to reset values such as the depth mask, stencil
- * mask, and corresponding test flags to their original values.
- *
- * The input StyleRenderParameters object has a `TransformState state` member that can be queried
- * for information about the current map view.
- */
- virtual void render(const StyleRenderParameters&) const = 0;
+ CustomLayer(const std::string& id,
+ CustomLayerInitializeFunction,
+ CustomLayerRenderFunction,
+ CustomLayerDeinitializeFunction,
+ void* context);
+
+ CustomLayer(const CustomLayer&);
+ ~CustomLayer();
+
+ void initialize();
+ void render(const TransformState&) const;
+
+private:
+ std::unique_ptr<StyleLayer> clone() const final;
void parseLayout(const JSVal&) final {}
void parsePaints(const JSVal&) final {}
@@ -42,6 +31,11 @@ public:
bool recalculate(const StyleCalculationParameters&) final;
std::unique_ptr<Bucket> createBucket(StyleBucketParameters&) const final;
+
+ CustomLayerInitializeFunction initializeFn;
+ CustomLayerRenderFunction renderFn;
+ CustomLayerDeinitializeFunction deinitializeFn;
+ void* context;
};
} // namespace mbgl
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 1896e7d29b..4336c2556d 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -8,6 +8,7 @@
#include <mbgl/annotation/point_annotation.hpp>
#include <mbgl/annotation/shape_annotation.hpp>
#include <mbgl/style/style_layer.hpp>
+#include <mbgl/layer/custom_layer.hpp>
#include <mbgl/util/projection.hpp>
#include <mbgl/util/thread.hpp>
@@ -425,12 +426,15 @@ LatLngBounds Map::getBoundsForAnnotations(const AnnotationIDs& annotations) {
#pragma mark - Style API
-void Map::addLayer(std::unique_ptr<StyleLayer> layer) {
- context->invoke(&MapContext::addLayer, std::move(layer), mapbox::util::optional<std::string>());
-}
-
-void Map::addLayer(std::unique_ptr<StyleLayer> layer, const std::string& before) {
- context->invoke(&MapContext::addLayer, std::move(layer), before);
+void Map::addCustomLayer(const std::string& id,
+ CustomLayerInitializeFunction initialize,
+ CustomLayerRenderFunction render,
+ CustomLayerDeinitializeFunction deinitialize,
+ void* context_,
+ const char* before) {
+ context->invoke(&MapContext::addLayer,
+ std::make_unique<CustomLayer>(id, initialize, render, deinitialize, context_),
+ before ? std::string(before) : mapbox::util::optional<std::string>());
}
#pragma mark - Toggles
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index cab9d49212..261cd895a5 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -239,7 +239,7 @@ void Painter::renderPass(RenderPass pass_,
renderBackground(*layer.as<BackgroundLayer>());
} else if (layer.is<CustomLayer>()) {
MBGL_DEBUG_GROUP(layer.id + " - custom");
- layer.as<CustomLayer>()->render(StyleRenderParameters(state));
+ layer.as<CustomLayer>()->render(state);
config.setDirty();
} else {
MBGL_DEBUG_GROUP(layer.id + " - " + std::string(item.tile->id));
diff --git a/test/api/custom_layer.cpp b/test/api/custom_layer.cpp
index 816a53dd35..e98e2cfc0b 100644
--- a/test/api/custom_layer.cpp
+++ b/test/api/custom_layer.cpp
@@ -13,11 +13,8 @@ using namespace mbgl;
static const GLchar * vertexShaderSource = "attribute vec2 a_pos; void main() { gl_Position = vec4(a_pos, 0, 1); }";
static const GLchar * fragmentShaderSource = "void main() { gl_FragColor = vec4(0, 1, 0, 1); }";
-class TestLayer : public CustomLayer {
+class TestLayer {
public:
- TestLayer() : CustomLayer("custom") {}
- TestLayer(const TestLayer& copy) : CustomLayer(copy) {} // Don't copy GL resources
-
~TestLayer() {
if (program) {
MBGL_CHECK_ERROR(glDeleteBuffers(1, &buffer));
@@ -29,7 +26,7 @@ public:
}
}
- void initialize() override {
+ void initialize() {
program = MBGL_CHECK_ERROR(glCreateProgram());
vertexShader = MBGL_CHECK_ERROR(glCreateShader(GL_VERTEX_SHADER));
fragmentShader = MBGL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER));
@@ -49,7 +46,7 @@ public:
MBGL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), background, GL_STATIC_DRAW));
}
- void render(const StyleRenderParameters&) const override {
+ void render() {
MBGL_CHECK_ERROR(glUseProgram(program));
MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, buffer));
MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
@@ -59,10 +56,6 @@ public:
MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
}
- std::unique_ptr<StyleLayer> clone() const override {
- return std::make_unique<TestLayer>(*this);
- }
-
GLuint program = 0;
GLuint vertexShader = 0;
GLuint fragmentShader = 0;
@@ -77,7 +70,17 @@ TEST(CustomLayer, Basic) {
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
- map.addLayer(std::make_unique<TestLayer>());
+ map.addCustomLayer(
+ "custom",
+ [] (void* context) {
+ reinterpret_cast<TestLayer*>(context)->initialize();
+ },
+ [] (void* context, const CustomLayerRenderParameters&) {
+ reinterpret_cast<TestLayer*>(context)->render();
+ },
+ [] (void* context) {
+ delete reinterpret_cast<TestLayer*>(context);
+ }, new TestLayer());
test::checkImage("test/fixtures/custom_layer/basic", test::render(map));
}