[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).
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[
|
||||
"mbgl-glfw",
|
||||
"/src/workspace/next-linux-gcc8-release/bin/mbgl-glfw",
|
||||
7205192
|
||||
7323976
|
||||
],
|
||||
[
|
||||
"mbgl-offline",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[
|
||||
"mbgl-glfw",
|
||||
"/src/workspace/next-macos-xcode11-release/bin/mbgl-glfw",
|
||||
5439932
|
||||
5502420
|
||||
],
|
||||
[
|
||||
"mbgl-offline",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
188
platform/glfw/test_writer.cpp
Normal file
188
platform/glfw/test_writer.cpp
Normal file
@@ -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();
|
||||
}
|
||||
29
platform/glfw/test_writer.hpp
Normal file
29
platform/glfw/test_writer.hpp
Normal file
@@ -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;
|
||||
};
|
||||
Reference in New Issue
Block a user