summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <tmpsantos@gmail.com>2019-12-02 16:20:50 +0200
committerThiago Marcos P. Santos <tmpsantos@gmail.com>2019-12-09 16:09:16 +0200
commit71054c8b609f02403bf28e91c4c4ab14f1468e5d (patch)
tree9ecdcaf803bd4b5c621aab53da6f5d1af9744c8f
parent6d425f8a7e7e4d210bd6e81d656245d0b1b80266 (diff)
downloadqtlocation-mapboxgl-71054c8b609f02403bf28e91c4c4ab14f1468e5d.tar.gz
[glfw] Add static render test creator
Press F1 to create a render test for the current view. The test will be created at the base folder (current if nothing is provided) + /NNNN (the next free entry).
-rw-r--r--cmake/glfw.cmake2
-rw-r--r--metrics/tests/binary-size/linux-gcc8/metrics.json2
-rw-r--r--metrics/tests/binary-size/macos-xcode11/metrics.json2
-rw-r--r--next/platform/glfw/CMakeLists.txt3
-rw-r--r--platform/glfw/glfw_view.cpp28
-rw-r--r--platform/glfw/glfw_view.hpp4
-rw-r--r--platform/glfw/main.cpp6
-rw-r--r--platform/glfw/test_writer.cpp188
-rw-r--r--platform/glfw/test_writer.hpp29
9 files changed, 256 insertions, 8 deletions
diff --git a/cmake/glfw.cmake b/cmake/glfw.cmake
index 89a7768ad3..d595518954 100644
--- a/cmake/glfw.cmake
+++ b/cmake/glfw.cmake
@@ -12,6 +12,8 @@ target_sources(mbgl-glfw
PRIVATE platform/glfw/glfw_renderer_frontend.cpp
PRIVATE platform/glfw/settings_json.hpp
PRIVATE platform/glfw/settings_json.cpp
+ PRIVATE platform/glfw/test_writer.hpp
+ PRIVATE platform/glfw/test_writer.cpp
)
target_include_directories(mbgl-glfw
diff --git a/metrics/tests/binary-size/linux-gcc8/metrics.json b/metrics/tests/binary-size/linux-gcc8/metrics.json
index d8238e95f6..5b8e1f5bec 100644
--- a/metrics/tests/binary-size/linux-gcc8/metrics.json
+++ b/metrics/tests/binary-size/linux-gcc8/metrics.json
@@ -3,7 +3,7 @@
[
"mbgl-glfw",
"/src/workspace/next-linux-gcc8-release/bin/mbgl-glfw",
- 7205192
+ 7323976
],
[
"mbgl-offline",
diff --git a/metrics/tests/binary-size/macos-xcode11/metrics.json b/metrics/tests/binary-size/macos-xcode11/metrics.json
index 9a4ffebd13..41886e8caf 100644
--- a/metrics/tests/binary-size/macos-xcode11/metrics.json
+++ b/metrics/tests/binary-size/macos-xcode11/metrics.json
@@ -3,7 +3,7 @@
[
"mbgl-glfw",
"/src/workspace/next-macos-xcode11-release/bin/mbgl-glfw",
- 5439932
+ 5502420
],
[
"mbgl-offline",
diff --git a/next/platform/glfw/CMakeLists.txt b/next/platform/glfw/CMakeLists.txt
index e4c0920a44..b0263362a7 100644
--- a/next/platform/glfw/CMakeLists.txt
+++ b/next/platform/glfw/CMakeLists.txt
@@ -10,6 +10,7 @@ add_executable(
${MBGL_ROOT}/platform/glfw/glfw_gl_backend.cpp
${MBGL_ROOT}/platform/glfw/glfw_renderer_frontend.cpp
${MBGL_ROOT}/platform/glfw/settings_json.cpp
+ ${MBGL_ROOT}/platform/glfw/test_writer.cpp
)
target_include_directories(
@@ -30,6 +31,8 @@ target_link_libraries(
PRIVATE
${GLFW_LIBRARIES}
Mapbox::Base::Extras::args
+ Mapbox::Base::Extras::filesystem
+ Mapbox::Base::Extras::rapidjson
Mapbox::Map
OpenGL::GL
mbgl-vendor-cheap-ruler-cpp
diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp
index 74dda734c0..3d10f2c654 100644
--- a/platform/glfw/glfw_view.cpp
+++ b/platform/glfw/glfw_view.cpp
@@ -2,6 +2,7 @@
#include "glfw_backend.hpp"
#include "glfw_renderer_frontend.hpp"
#include "ny_route.hpp"
+#include "test_writer.hpp"
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/gfx/backend.hpp>
@@ -36,6 +37,7 @@
#include <cassert>
#include <cstdlib>
+#include <iostream>
void glfwError(int error, const char *description) {
mbgl::Log::Error(mbgl::Event::OpenGL, "GLFW error (%i): %s", error, description);
@@ -124,8 +126,8 @@ GLFWView::GLFWView(bool fullscreen_, bool benchmark_)
printf("- Press `E` to insert an example building extrusion layer\n");
printf("- Press `O` to toggle online connectivity\n");
printf("- Press `Z` to cycle through north orientations\n");
- printf("- Prezz `X` to cycle through the viewport modes\n");
- printf("- Press `I` to Delete existing database and re-initialize\n");
+ printf("- Press `X` to cycle through the viewport modes\n");
+ printf("- Press `I` to delete existing database and re-initialize\n");
printf("- Press `A` to cycle through Mapbox offices in the world + dateline monument\n");
printf("- Press `B` to cycle through the color, stencil, and depth buffer\n");
printf("- Press `D` to cycle through camera bounds: inside, crossing IDL at left, crossing IDL at right, and disabled\n");
@@ -138,10 +140,12 @@ GLFWView::GLFWView(bool fullscreen_, bool benchmark_)
printf("- Press `K` to add a random custom runtime imagery annotation\n");
printf("- Press `L` to add a random line annotation\n");
printf("- Press `W` to pop the last-added annotation off\n");
- printf("\n");
printf("- Press `P` to pause tile requests\n");
- printf("- `Control` + mouse drag to rotate\n");
- printf("- `Shift` + mouse drag to tilt\n");
+ printf("\n");
+ printf("- Hold `Control` + mouse drag to rotate\n");
+ printf("- Hold `Shift` + mouse drag to tilt\n");
+ printf("\n");
+ printf("- Press `F1` to generate a render test for the current view\n");
printf("\n");
printf("- Press `Tab` to cycle through the map debug options\n");
printf("- Press `Esc` to quit\n");
@@ -370,6 +374,20 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
: mbgl::style::VisibilityType::Visible);
}
} break;
+ case GLFW_KEY_F1: {
+ bool success = TestWriter()
+ .withInitialSize(mbgl::Size(view->width, view->height))
+ .withStyle(view->map->getStyle())
+ .withCameraOptions(view->map->getCameraOptions())
+ .write(view->testDirectory);
+
+ if (success) {
+ mbgl::Log::Info(mbgl::Event::General, "Render test created!");
+ } else {
+ mbgl::Log::Error(mbgl::Event::General,
+ "Fail to create render test! Base directory does not exist or permission denied.");
+ }
+ } break;
}
}
diff --git a/platform/glfw/glfw_view.hpp b/platform/glfw/glfw_view.hpp
index 9233bddfb9..e9867f14da 100644
--- a/platform/glfw/glfw_view.hpp
+++ b/platform/glfw/glfw_view.hpp
@@ -29,6 +29,8 @@ public:
mbgl::gfx::RendererBackend& getRendererBackend();
+ void setTestDirectory(std::string dir) { testDirectory = std::move(dir); };
+
// Callback called when the user presses the key mapped to style change.
// The expected action is to set a new style, different to the current one.
void setChangeStyleCallback(std::function<void()> callback);
@@ -105,6 +107,8 @@ private:
GLFWRendererFrontend* rendererFrontend = nullptr;
std::unique_ptr<GLFWBackend> backend;
+ std::string testDirectory = ".";
+
bool fullscreen = false;
const bool benchmark = false;
bool tracking = false;
diff --git a/platform/glfw/main.cpp b/platform/glfw/main.cpp
index 3c1e50e196..8f134804f0 100644
--- a/platform/glfw/main.cpp
+++ b/platform/glfw/main.cpp
@@ -43,7 +43,9 @@ int main(int argc, char *argv[]) {
args::Flag benchmarkFlag(argumentParser, "benchmark", "Toggle benchmark", {'b', "benchmark"});
args::Flag offlineFlag(argumentParser, "offline", "Toggle offline", {'o', "offline"});
- args::ValueFlag<std::string> backendValue(argumentParser, "Backend", "Rendering backend", {"backend"});
+ args::ValueFlag<std::string> testDirValue(
+ argumentParser, "directory", "Root directory for test generation", {"testDir"});
+ args::ValueFlag<std::string> backendValue(argumentParser, "backend", "Rendering backend", {"backend"});
args::ValueFlag<std::string> styleValue(argumentParser, "URL", "Map stylesheet", {'s', "style"});
args::ValueFlag<std::string> cacheDBValue(argumentParser, "file", "Cache database file name", {'c', "cache"});
args::ValueFlag<double> lonValue(argumentParser, "degrees", "Longitude", {'x', "lon"});
@@ -128,6 +130,8 @@ int main(int argc, char *argv[]) {
.withPitch(settings.pitch));
map.setDebug(mbgl::MapDebugOptions(settings.debug));
+ if (testDirValue) view->setTestDirectory(args::get(testDirValue));
+
view->setOnlineStatusCallback([&settings, fileSource]() {
settings.online = !settings.online;
fileSource->setOnlineStatus(settings.online);
diff --git a/platform/glfw/test_writer.cpp b/platform/glfw/test_writer.cpp
new file mode 100644
index 0000000000..d125170aed
--- /dev/null
+++ b/platform/glfw/test_writer.cpp
@@ -0,0 +1,188 @@
+#include "test_writer.hpp"
+
+#include <rapidjson/prettywriter.h>
+#include <rapidjson/stringbuffer.h>
+#include <rapidjson/writer.h>
+#include <ghc/filesystem.hpp>
+
+#include <cmath>
+#include <fstream>
+
+using Writer = rapidjson::PrettyWriter<rapidjson::StringBuffer>;
+
+class TestOperation {
+public:
+ virtual ~TestOperation() = default;
+
+ virtual void serialize(Writer& writer) const = 0;
+};
+
+class SetCamera final : public TestOperation {
+public:
+ SetCamera(const mbgl::CameraOptions& camera_) : camera(camera_) {}
+
+ void serialize(Writer& writer) const override {
+ if (camera.zoom) {
+ writer.StartArray();
+ writer.String("setZoom");
+ writer.Double(*camera.zoom);
+ writer.EndArray();
+ }
+
+ if (camera.bearing && *camera.bearing != 0.) {
+ writer.StartArray();
+ writer.String("setBearing");
+ writer.Double(*camera.bearing);
+ writer.EndArray();
+ }
+
+ if (camera.pitch && *camera.pitch != 0.) {
+ writer.StartArray();
+ writer.String("setPitch");
+ writer.Int(std::round(*camera.pitch));
+ writer.EndArray();
+ }
+
+ writer.StartArray();
+ writer.String("setCenter");
+ writer.StartArray();
+ writer.Double(camera.center->longitude());
+ writer.Double(camera.center->latitude());
+ writer.EndArray();
+ writer.EndArray();
+ }
+
+private:
+ mbgl::CameraOptions camera;
+};
+
+class SetStyle final : public TestOperation {
+public:
+ SetStyle(const mbgl::style::Style& style) : url(style.getURL()) {}
+
+ void serialize(Writer& writer) const override {
+ writer.StartArray();
+ writer.String("setStyle");
+ writer.String(url);
+ writer.EndArray();
+ }
+
+private:
+ std::string url;
+};
+
+class SetInitialSize final : public TestOperation {
+public:
+ SetInitialSize(const mbgl::Size& size) : width(size.width), height(size.height) {}
+
+ void serialize(Writer& writer) const override {
+ writer.Key("width");
+ writer.Int(width);
+
+ writer.Key("height");
+ writer.Int(height);
+ }
+
+private:
+ uint32_t width;
+ uint32_t height;
+};
+
+TestWriter::TestWriter() = default;
+
+TestWriter::~TestWriter() = default;
+
+TestWriter& TestWriter::withCameraOptions(const mbgl::CameraOptions& camera) {
+ operations.emplace_back(std::make_unique<SetCamera>(camera));
+
+ return *this;
+}
+
+TestWriter& TestWriter::withStyle(const mbgl::style::Style& style) {
+ operations.emplace_back(std::make_unique<SetStyle>(style));
+
+ return *this;
+}
+
+TestWriter& TestWriter::withInitialSize(const mbgl::Size& size) {
+ assert(initialSize == nullptr);
+ initialSize = std::make_unique<SetInitialSize>(size);
+
+ return *this;
+}
+
+bool TestWriter::write(const std::string& dir) const {
+ namespace fs = ghc::filesystem;
+
+ fs::path rootDir(dir);
+ if (!fs::exists(rootDir)) {
+ return false;
+ }
+
+ fs::path testDir;
+ for (int i = 0; i < 1000; ++i) {
+ std::string suffix = std::to_string(i);
+ suffix.insert(suffix.begin(), 3 - suffix.length(), '0');
+
+ testDir = rootDir / suffix;
+ if (!fs::exists(testDir)) {
+ break;
+ }
+ }
+
+ if (!fs::create_directory(testDir)) {
+ return false;
+ }
+
+ fs::path styleFile = testDir / "style.json";
+
+ std::ofstream out;
+ out.open(styleFile.string(), std::ios::out);
+ out << serialize();
+
+ return out.is_open() && out.good();
+}
+
+std::string TestWriter::serialize() const {
+ rapidjson::StringBuffer s;
+ Writer writer(s);
+
+ writer.StartObject();
+
+ writer.Key("version");
+ writer.Int(8);
+
+ writer.Key("metadata");
+ writer.StartObject();
+
+ writer.Key("test");
+ writer.StartObject();
+
+ writer.Key("operations");
+ writer.StartArray();
+
+ for (const auto& operation : operations) {
+ operation->serialize(writer);
+ }
+
+ writer.EndArray();
+
+ if (initialSize) {
+ initialSize->serialize(writer);
+ }
+
+ writer.EndObject();
+ writer.EndObject();
+
+ writer.Key("sources");
+ writer.StartObject();
+ writer.EndObject();
+
+ writer.Key("layers");
+ writer.StartArray();
+ writer.EndArray();
+
+ writer.EndObject();
+
+ return s.GetString();
+}
diff --git a/platform/glfw/test_writer.hpp b/platform/glfw/test_writer.hpp
new file mode 100644
index 0000000000..8e41e3e49a
--- /dev/null
+++ b/platform/glfw/test_writer.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <mbgl/map/camera.hpp>
+#include <mbgl/style/style.hpp>
+#include <mbgl/util/size.hpp>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+class TestOperation;
+
+class TestWriter final {
+public:
+ TestWriter();
+ ~TestWriter();
+
+ TestWriter& withCameraOptions(const mbgl::CameraOptions&);
+ TestWriter& withStyle(const mbgl::style::Style&);
+ TestWriter& withInitialSize(const mbgl::Size&);
+
+ bool write(const std::string& dir) const;
+
+private:
+ std::string serialize() const;
+
+ std::vector<std::unique_ptr<TestOperation>> operations;
+ std::unique_ptr<TestOperation> initialSize;
+};