diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-12-09 16:52:59 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-12-11 12:44:54 -0800 |
commit | 65b3220368f669dd7ddbcb06e95019319e0c536a (patch) | |
tree | f0e5a437f11feb231336dc7aa4ce67fd07ebab92 | |
parent | 78691fa9e61dadbb73be28bcac1a606d7a029ad4 (diff) | |
download | qtlocation-mapboxgl-65b3220368f669dd7ddbcb06e95019319e0c536a.tar.gz |
[core] Reduce custom layer API to lowest common denominator
-rw-r--r-- | include/mbgl/map/map.hpp | 11 | ||||
-rw-r--r-- | include/mbgl/style/types.hpp | 39 | ||||
-rw-r--r-- | src/mbgl/layer/custom_layer.cpp | 49 | ||||
-rw-r--r-- | src/mbgl/layer/custom_layer.hpp | 46 | ||||
-rw-r--r-- | src/mbgl/map/map.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 2 | ||||
-rw-r--r-- | test/api/custom_layer.cpp | 25 |
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)); } |