From 32bd1d54fa777035920b58e653905e4592ef187c Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 21 Jul 2017 16:36:31 -0700 Subject: [node, tests] Consolidate headless rendering logic in HeadlessFrontend --- test/api/annotations.test.cpp | 62 ++++++++---------- test/api/api_misuse.test.cpp | 13 +--- test/api/custom_layer.test.cpp | 16 ++--- test/api/query.test.cpp | 47 ++++++-------- test/gl/object.test.cpp | 5 +- test/map/map.test.cpp | 94 +++++++++++---------------- test/map/prefetch.test.cpp | 16 ++--- test/src/mbgl/test/stub_renderer_frontend.cpp | 52 --------------- test/src/mbgl/test/stub_renderer_frontend.hpp | 44 ------------- test/src/mbgl/test/util.cpp | 17 ----- test/src/mbgl/test/util.hpp | 7 -- test/util/memory.test.cpp | 78 ++++++++-------------- test/util/offscreen_texture.test.cpp | 21 +++--- 13 files changed, 135 insertions(+), 337 deletions(-) delete mode 100644 test/src/mbgl/test/stub_renderer_frontend.cpp delete mode 100644 test/src/mbgl/test/stub_renderer_frontend.hpp (limited to 'test') diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp index 878ef90831..d6476f9a3e 100644 --- a/test/api/annotations.test.cpp +++ b/test/api/annotations.test.cpp @@ -6,14 +6,11 @@ #include #include #include -#include -#include -#include #include #include #include #include -#include +#include using namespace mbgl; @@ -30,19 +27,16 @@ std::unique_ptr namedMarker(const std::string& name) { class AnnotationTest { public: util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; StubFileSource fileSource; ThreadPool threadPool { 4 }; float pixelRatio { 1 }; - StubRendererFrontend rendererFrontend { std::make_unique(backend, pixelRatio, fileSource, threadPool), view }; - Map map { rendererFrontend, MapObserver::nullObserver(), view.getSize(), pixelRatio, fileSource, + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Still }; void checkRendering(const char * name) { test::checkImage(std::string("test/fixtures/annotations/") + name, - test::render(map, view), 0.0002, 0.1); + frontend.render(map), 0.0002, 0.1); } }; @@ -160,7 +154,7 @@ TEST(Annotations, AddMultiple) { test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point { -10, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.addAnnotation(SymbolAnnotation { Point { 10, 0 }, "default_marker" }); test.checkRendering("add_multiple"); @@ -170,7 +164,7 @@ TEST(Annotations, NonImmediateAdd) { AnnotationTest test; test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); - test::render(test.map, test.view); + test.frontend.render(test.map); Polygon polygon = { {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }; FillAnnotation annotation { polygon }; @@ -188,7 +182,7 @@ TEST(Annotations, UpdateSymbolAnnotationGeometry) { test.map.addAnnotationImage(namedMarker("flipped_marker")); AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.updateAnnotation(point, SymbolAnnotation { Point { -10, 0 }, "default_marker" }); test.checkRendering("update_point"); @@ -202,7 +196,7 @@ TEST(Annotations, UpdateSymbolAnnotationIcon) { test.map.addAnnotationImage(namedMarker("flipped_marker")); AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.updateAnnotation(point, SymbolAnnotation { Point { 0, 0 }, "flipped_marker" }); test.checkRendering("update_icon"); @@ -218,7 +212,7 @@ TEST(Annotations, UpdateLineAnnotationGeometry) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID line = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.geometry = LineString {{ { 0, 0 }, { -45, -45 } }}; test.map.updateAnnotation(line, annotation); @@ -235,7 +229,7 @@ TEST(Annotations, UpdateLineAnnotationStyle) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID line = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.color = Color::green(); annotation.width = { 2 }; @@ -252,7 +246,7 @@ TEST(Annotations, UpdateFillAnnotationGeometry) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID fill = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.geometry = Polygon { {{ { 0, 0 }, { 0, 45 }, { 45, 0 } }} }; test.map.updateAnnotation(fill, annotation); @@ -269,7 +263,7 @@ TEST(Annotations, UpdateFillAnnotationStyle) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID fill = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.color = Color::green(); test.map.updateAnnotation(fill, annotation); @@ -283,7 +277,7 @@ TEST(Annotations, RemovePoint) { test.map.addAnnotationImage(namedMarker("default_marker")); AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.removeAnnotation(point); test.checkRendering("remove_point"); @@ -300,7 +294,7 @@ TEST(Annotations, RemoveShape) { test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID shape = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.removeAnnotation(shape); test.checkRendering("remove_shape"); @@ -312,7 +306,7 @@ TEST(Annotations, ImmediateRemoveShape) { test.map.removeAnnotation(test.map.addAnnotation(LineAnnotation { LineString() })); test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); - test::render(test.map, test.view); + test.frontend.render(test.map); } TEST(Annotations, SwitchStyle) { @@ -322,7 +316,7 @@ TEST(Annotations, SwitchStyle) { test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); test.checkRendering("switch_style"); @@ -335,7 +329,7 @@ TEST(Annotations, ReaddImage) { test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.addAnnotationImage(std::make_unique("default_marker", namedImage("flipped_marker"), 1.0)); test.checkRendering("readd_image"); @@ -349,14 +343,14 @@ TEST(Annotations, QueryRenderedFeatures) { test.map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); test.map.addAnnotation(SymbolAnnotation { Point { 0, 50 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); - auto features = test.rendererFrontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); + auto features = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); EXPECT_EQ(features.size(), 1u); EXPECT_TRUE(!!features[0].id); EXPECT_EQ(*features[0].id, uint64_t(0)); - auto features2 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 50, 0 })); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 50, 0 })); EXPECT_EQ(features2.size(), 1u); EXPECT_TRUE(!!features2[0].id); EXPECT_EQ(*features2[0].id, uint64_t(1)); @@ -365,7 +359,7 @@ TEST(Annotations, QueryRenderedFeatures) { TEST(Annotations, QueryFractionalZoomLevels) { AnnotationTest test; - auto viewSize = test.view.getSize(); + auto viewSize = test.frontend.getSize(); auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } }; test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); @@ -381,8 +375,8 @@ TEST(Annotations, QueryFractionalZoomLevels) { test.map.setLatLngZoom({ 5, 5 }, 0); for (uint16_t zoomSteps = 10; zoomSteps <= 20; ++zoomSteps) { test.map.setZoom(zoomSteps / 10.0); - test::render(test.map, test.view); - auto features = test.rendererFrontend.getRenderer()->queryRenderedFeatures(box); + test.frontend.render(test.map); + auto features = test.frontend.getRenderer()->queryRenderedFeatures(box); // Filter out repeated features. // See 'edge-cases/null-island' query-test for reference. @@ -397,7 +391,7 @@ TEST(Annotations, QueryFractionalZoomLevels) { TEST(Annotations, VisibleFeatures) { AnnotationTest test; - auto viewSize = test.view.getSize(); + auto viewSize = test.frontend.getSize(); auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } }; test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); @@ -413,9 +407,9 @@ TEST(Annotations, VisibleFeatures) { // Change bearing *after* adding annotations causes them to be reordered. test.map.setBearing(45); - test::render(test.map, test.view); + test.frontend.render(test.map); - auto features = test.rendererFrontend.getRenderer()->queryRenderedFeatures(box, {}); + auto features = test.frontend.getRenderer()->queryRenderedFeatures(box, {}); auto sortID = [](const Feature& lhs, const Feature& rhs) { return lhs.id < rhs.id; }; auto sameID = [](const Feature& lhs, const Feature& rhs) { return lhs.id == rhs.id; }; std::sort(features.begin(), features.end(), sortID); @@ -424,8 +418,8 @@ TEST(Annotations, VisibleFeatures) { test.map.setBearing(0); test.map.setZoom(4); - test::render(test.map, test.view); - features = test.rendererFrontend.getRenderer()->queryRenderedFeatures(box); + test.frontend.render(test.map); + features = test.frontend.getRenderer()->queryRenderedFeatures(box); std::sort(features.begin(), features.end(), sortID); features.erase(std::unique(features.begin(), features.end(), sameID), features.end()); EXPECT_EQ(features.size(), ids.size()); diff --git a/test/api/api_misuse.test.cpp b/test/api/api_misuse.test.cpp index 9f53b763be..690c1548e5 100644 --- a/test/api/api_misuse.test.cpp +++ b/test/api/api_misuse.test.cpp @@ -4,11 +4,8 @@ #include #include -#include -#include -#include +#include #include -#include #include #include #include @@ -24,16 +21,12 @@ TEST(API, RenderWithoutCallback) { util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 128, 512 } }; StubFileSource fileSource; ThreadPool threadPool(4); float pixelRatio { 1 }; - StubRendererFrontend rendererFrontend { - std::make_unique(backend, pixelRatio, fileSource, threadPool), view }; + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; - auto map = std::make_unique(rendererFrontend, MapObserver::nullObserver(), view.getSize(), + auto map = std::make_unique(frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Still); map->renderStill(nullptr); diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp index 972485338f..1c514aeca2 100644 --- a/test/api/custom_layer.test.cpp +++ b/test/api/custom_layer.test.cpp @@ -2,16 +2,12 @@ #include #include -#include -#include -#include #include #include -#include +#include #include #include #include -#include #include #include #include @@ -89,14 +85,11 @@ public: TEST(CustomLayer, Basic) { util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets"); ThreadPool threadPool(4); float pixelRatio { 1 }; - StubRendererFrontend rendererFrontend { std::make_unique(backend, pixelRatio, fileSource, threadPool), view }; - Map map(rendererFrontend, MapObserver::nullObserver(), view.getSize(), pixelRatio, fileSource, + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Still); map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json")); map.setLatLngZoom({ 37.8, -122.5 }, 10); @@ -117,6 +110,5 @@ TEST(CustomLayer, Basic) { layer->setFillColor(Color{ 1.0, 1.0, 0.0, 1.0 }); map.getStyle().addLayer(std::move(layer)); - test::checkImage("test/fixtures/custom_layer/basic", test::render(map, view), 0.0006, 0.1); - + test::checkImage("test/fixtures/custom_layer/basic", frontend.render(map), 0.0006, 0.1); } diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp index a5224222cb..3f3825eb72 100644 --- a/test/api/query.test.cpp +++ b/test/api/query.test.cpp @@ -1,7 +1,4 @@ #include -#include -#include -#include #include #include #include @@ -12,7 +9,7 @@ #include #include #include -#include +#include using namespace mbgl; using namespace mbgl::style; @@ -26,19 +23,15 @@ public: map.getStyle().addImage(std::make_unique("test-icon", decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")), 1.0)); - test::render(map, view); + frontend.render(map); } util::RunLoop loop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; StubFileSource fileSource; ThreadPool threadPool { 4 }; float pixelRatio { 1 }; - StubRendererFrontend rendererFrontend { - std::make_unique(backend, pixelRatio, fileSource, threadPool), view }; - Map map { rendererFrontend, MapObserver::nullObserver(), view.getSize(), pixelRatio, fileSource, + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Still }; }; @@ -47,10 +40,10 @@ public: TEST(Query, QueryRenderedFeatures) { QueryTest test; - auto features1 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); EXPECT_EQ(features1.size(), 4u); - auto features2 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 9, 9 })); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 9, 9 })); EXPECT_EQ(features2.size(), 0u); } @@ -59,16 +52,16 @@ TEST(Query, QueryRenderedFeaturesFilterLayer) { auto zz = test.map.pixelForLatLng({ 0, 0 }); - auto features1 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1"}}, {}}); + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1"}}, {}}); EXPECT_EQ(features1.size(), 1u); - auto features2 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1", "layer2" }}, {}}); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1", "layer2" }}, {}}); EXPECT_EQ(features2.size(), 2u); - auto features3 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar" }}, {}}); + auto features3 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar" }}, {}}); EXPECT_EQ(features3.size(), 0u); - auto features4 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar", "layer3" }}, {}}); + auto features4 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar", "layer3" }}, {}}); EXPECT_EQ(features4.size(), 1u); } @@ -78,22 +71,22 @@ TEST(Query, QueryRenderedFeaturesFilter) { auto zz = test.map.pixelForLatLng({ 0, 0 }); const EqualsFilter eqFilter = { "key1", std::string("value1") }; - auto features1 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{}, { eqFilter }}); + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{}, { eqFilter }}); EXPECT_EQ(features1.size(), 1u); const IdentifierNotEqualsFilter idNotEqFilter = { std::string("feature1") }; - auto features2 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer4" }}, { idNotEqFilter }}); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer4" }}, { idNotEqFilter }}); EXPECT_EQ(features2.size(), 0u); const GreaterThanFilter gtFilter = { "key2", 1.0 }; - auto features3 = test.rendererFrontend.getRenderer()->queryRenderedFeatures(zz, {{ }, { gtFilter }}); + auto features3 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{ }, { gtFilter }}); EXPECT_EQ(features3.size(), 1u); } TEST(Query, QuerySourceFeatures) { QueryTest test; - auto features1 = test.rendererFrontend.getRenderer()->querySourceFeatures("source3"); + auto features1 = test.frontend.getRenderer()->querySourceFeatures("source3"); EXPECT_EQ(features1.size(), 1u); } @@ -101,15 +94,15 @@ TEST(Query, QuerySourceFeaturesOptionValidation) { QueryTest test; // GeoJSONSource, doesn't require a layer id - auto features = test.rendererFrontend.getRenderer()->querySourceFeatures("source3"); + auto features = test.frontend.getRenderer()->querySourceFeatures("source3"); ASSERT_EQ(features.size(), 1u); // VectorSource, requires a layer id - features = test.rendererFrontend.getRenderer()->querySourceFeatures("source5"); + features = test.frontend.getRenderer()->querySourceFeatures("source5"); ASSERT_EQ(features.size(), 0u); // RasterSource, not supported - features = test.rendererFrontend.getRenderer()->querySourceFeatures("source6"); + features = test.frontend.getRenderer()->querySourceFeatures("source6"); ASSERT_EQ(features.size(), 0u); } @@ -117,15 +110,15 @@ TEST(Query, QuerySourceFeaturesFilter) { QueryTest test; const EqualsFilter eqFilter = { "key1", std::string("value1") }; - auto features1 = test.rendererFrontend.getRenderer()->querySourceFeatures("source4", {{}, { eqFilter }}); + auto features1 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { eqFilter }}); EXPECT_EQ(features1.size(), 1u); const IdentifierNotEqualsFilter idNotEqFilter = { std::string("feature1") }; - auto features2 = test.rendererFrontend.getRenderer()->querySourceFeatures("source4", {{}, { idNotEqFilter }}); + auto features2 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { idNotEqFilter }}); EXPECT_EQ(features2.size(), 0u); const GreaterThanFilter gtFilter = { "key2", 1.0 }; - auto features3 = test.rendererFrontend.getRenderer()->querySourceFeatures("source4", {{}, { gtFilter }}); + auto features3 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { gtFilter }}); EXPECT_EQ(features3.size(), 1u); } diff --git a/test/gl/object.test.cpp b/test/gl/object.test.cpp index 30699718b3..8046927c54 100644 --- a/test/gl/object.test.cpp +++ b/test/gl/object.test.cpp @@ -2,8 +2,6 @@ #include #include -#include - #include #include @@ -47,9 +45,8 @@ TEST(GLObject, Value) { } TEST(GLObject, Store) { - HeadlessBackend backend; + HeadlessBackend backend { { 256, 256 } }; BackendScope scope { backend }; - OffscreenView view(backend.getContext()); gl::Context context; EXPECT_TRUE(context.empty()); diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 3e8f8696e1..95d652f2af 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -4,16 +4,12 @@ #include #include -#include -#include -#include -#include #include +#include #include #include #include #include -#include #include #include #include @@ -21,7 +17,6 @@ #include #include #include -#include #include using namespace mbgl; @@ -53,30 +48,33 @@ public: didFinishLoadingStyleCallback(); } } - + + void onDidFinishRenderingFrame(RenderMode mode) final { + if (didFinishRenderingFrame) { + didFinishRenderingFrame(mode); + } + } + std::function onWillStartLoadingMapCallback; std::function onDidFinishLoadingMapCallback; std::function didFailLoadingMapCallback; std::function didFinishLoadingStyleCallback; + std::function didFinishRenderingFrame; }; template class MapTest { public: util::RunLoop runLoop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; FileSource fileSource; ThreadPool threadPool { 4 }; StubMapObserver observer; - StubRendererFrontend rendererFrontend; + HeadlessFrontend frontend; Map map; MapTest(float pixelRatio = 1, MapMode mode = MapMode::Still) - : rendererFrontend( - std::make_unique(backend, pixelRatio, fileSource, threadPool), view) - , map(rendererFrontend, observer, view.getSize(), pixelRatio, fileSource, threadPool, mode) { + : frontend(pixelRatio, fileSource, threadPool) + , map(frontend, observer, frontend.getSize(), pixelRatio, fileSource, threadPool, mode) { } template @@ -84,10 +82,8 @@ public: float pixelRatio = 1, MapMode mode = MapMode::Still, typename std::enable_if::value>::type* = 0) : fileSource { cachePath, assetRoot } - , rendererFrontend( - std::make_unique(backend, pixelRatio, fileSource, threadPool), - view) - , map(rendererFrontend, observer, view.getSize(), pixelRatio, fileSource, threadPool, mode) { + , frontend(pixelRatio, fileSource, threadPool) + , map(frontend, observer, frontend.getSize(), pixelRatio, fileSource, threadPool, mode) { } }; @@ -157,7 +153,7 @@ TEST(Map, Offline) { test.map.getStyle().loadURL(prefix + "style.json"); test::checkImage("test/fixtures/map/offline", - test::render(test.map, test.view), + test.frontend.render(test.map), 0.0015, 0.1); @@ -296,7 +292,7 @@ TEST(Map, StyleExpiredWithRender) { test.fileSource.respond(Resource::Style, response); EXPECT_EQ(1u, test.fileSource.requests.size()); - test::render(test.map, test.view); + test.frontend.render(test.map); EXPECT_EQ(1u, test.fileSource.requests.size()); test.fileSource.respond(Resource::Style, response); @@ -406,16 +402,18 @@ TEST(Map, AddLayer) { layer->setBackgroundColor({ { 1, 0, 0, 1 } }); test.map.getStyle().addLayer(std::move(layer)); - test::checkImage("test/fixtures/map/add_layer", test::render(test.map, test.view)); + test::checkImage("test/fixtures/map/add_layer", test.frontend.render(test.map)); } TEST(Map, WithoutVAOExtension) { MapTest test { ":memory:", "test/fixtures/api/assets" }; - test.backend.getContext().disableVAOExtension = true; + + BackendScope scope { *test.frontend.getBackend() }; + test.frontend.getBackend()->getContext().disableVAOExtension = true; test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json")); - test::checkImage("test/fixtures/map/no_vao", test::render(test.map, test.view), 0.002); + test::checkImage("test/fixtures/map/no_vao", test.frontend.render(test.map), 0.002); } TEST(Map, RemoveLayer) { @@ -428,7 +426,7 @@ TEST(Map, RemoveLayer) { test.map.getStyle().addLayer(std::move(layer)); test.map.getStyle().removeLayer("background"); - test::checkImage("test/fixtures/map/remove_layer", test::render(test.map, test.view)); + test::checkImage("test/fixtures/map/remove_layer", test.frontend.render(test.map)); } TEST(Map, DisabledSources) { @@ -486,9 +484,9 @@ TEST(Map, DisabledSources) { } )STYLE"); - test::checkImage("test/fixtures/map/disabled_layers/first", test::render(test.map, test.view)); + test::checkImage("test/fixtures/map/disabled_layers/first", test.frontend.render(test.map)); test.map.setZoom(0.5); - test::checkImage("test/fixtures/map/disabled_layers/second", test::render(test.map, test.view)); + test::checkImage("test/fixtures/map/disabled_layers/second", test.frontend.render(test.map)); } TEST(Map, DontLoadUnneededTiles) { @@ -533,16 +531,13 @@ TEST(Map, DontLoadUnneededTiles) { const double z = double(zoom) / 10; tiles.clear(); test.map.setZoom(z); - test::render(test.map, test.view); + test.frontend.render(test.map); EXPECT_EQ(referenceTiles[z], tiles) << "zoom level " << z; } } TEST(Map, TEST_DISABLED_ON_CI(ContinuousRendering)) { util::RunLoop runLoop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; ThreadPool threadPool { 4 }; DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets"); float pixelRatio { 1 }; @@ -551,39 +546,26 @@ TEST(Map, TEST_DISABLED_ON_CI(ContinuousRendering)) { util::Timer emergencyShutoff; emergencyShutoff.start(10s, 0s, [&] { - util::RunLoop::Get()->stop(); + runLoop.stop(); FAIL() << "Did not stop rendering"; }); util::Timer timer; - std::function isLoaded; - - StubRendererFrontend rendererFrontend { - std::make_unique(backend, pixelRatio, fileSource, threadPool), - [&](StubRendererFrontend& bridge) { - if (isLoaded()) { - // Abort the test after 1 second after the map loading fully. Note that a "fully loaded - // map" doesn't mean that we won't render anymore: we could still render fade in/fade - // out or other animations. - // If we are continuing to render indefinitely, the emergency shutoff above will trigger - // and the test will fail since the regular time will be constantly reset. - timer.start(1s, 0s, [&] { - util::RunLoop::Get()->stop(); - }); - } - - bridge.render(view); - } - }; - - Map map(rendererFrontend, MapObserver::nullObserver(), view.getSize(), pixelRatio, fileSource, - threadPool, MapMode::Continuous); + HeadlessFrontend frontend(pixelRatio, fileSource, threadPool); - isLoaded = [&] { - return map.isFullyLoaded(); + StubMapObserver observer; + observer.didFinishRenderingFrame = [&] (MapObserver::RenderMode) { + // Start a timer that ends the test one second from now. If we are continuing to render + // indefinitely, the timer will be constantly restarted and never trigger. Instead, the + // emergency shutoff above will trigger, failing the test. + timer.start(1s, 0s, [&] { + runLoop.stop(); + }); }; + Map map(frontend, observer, frontend.getSize(), pixelRatio, fileSource, threadPool, MapMode::Continuous); map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json")); - util::RunLoop::Get()->run(); + + runLoop.run(); } diff --git a/test/map/prefetch.test.cpp b/test/map/prefetch.test.cpp index 436bdc3b63..5c9a22d1bf 100644 --- a/test/map/prefetch.test.cpp +++ b/test/map/prefetch.test.cpp @@ -1,18 +1,14 @@ #include #include -#include -#include #include -#include -#include +#include #include #include #include #include #include #include -#include #include #include @@ -24,14 +20,10 @@ using namespace std::literals::string_literals; TEST(Map, PrefetchTiles) { util::RunLoop runLoop; - HeadlessBackend backend; - BackendScope scope(backend); - OffscreenView view(backend.getContext(), { 512, 512 }); ThreadPool threadPool(4); StubFileSource fileSource; - StubRendererFrontend rendererFrontend { - std::make_unique(backend, 1, fileSource, threadPool), view }; - Map map(rendererFrontend, MapObserver::nullObserver(), view.getSize(), 1, fileSource, threadPool, MapMode::Still); + HeadlessFrontend frontend { { 512, 512 }, 1, fileSource, threadPool }; + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), 1, fileSource, threadPool, MapMode::Still); std::vector tiles; @@ -65,7 +57,7 @@ TEST(Map, PrefetchTiles) { map.setLatLngZoom({ 40.726989, -73.992857 }, zoom); // Manhattan // Should always render the ideal tiles (i.e. a green map) - test::checkImage("test/fixtures/map/prefetch", test::render(map, view)); + test::checkImage("test/fixtures/map/prefetch", frontend.render(map)); ASSERT_TRUE(std::is_permutation(tiles.begin(), tiles.end(), expected.begin())); ASSERT_FALSE(tiles.empty()); diff --git a/test/src/mbgl/test/stub_renderer_frontend.cpp b/test/src/mbgl/test/stub_renderer_frontend.cpp deleted file mode 100644 index 7edcfd397e..0000000000 --- a/test/src/mbgl/test/stub_renderer_frontend.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include - -#include -#include - -namespace mbgl { - -StubRendererFrontend::StubRendererFrontend(std::unique_ptr renderer_, InvalidateCallback invalidate) - : renderer(std::move(renderer_)) - , asyncInvalidate([this, invalidate=std::move(invalidate)]() { - invalidate(*this); - }) { -} - -StubRendererFrontend::StubRendererFrontend(std::unique_ptr renderer_, View& view) - : renderer(std::move(renderer_)) - , asyncInvalidate([&]() { - this->render(view); - }) { -} - -StubRendererFrontend::~StubRendererFrontend() { - reset(); -} - -void StubRendererFrontend::reset() { - if (renderer) { - renderer.reset(); - } -} - -void StubRendererFrontend::setObserver(RendererObserver& observer) { - if (!renderer) return; - renderer->setObserver(&observer); -} - -void StubRendererFrontend::update(std::shared_ptr params) { - updateParameters = std::move(params); - asyncInvalidate.send(); -} - -void StubRendererFrontend::render(View& view) { - if (!updateParameters || !renderer) return; - renderer->render(view, *updateParameters); -} - -Renderer* StubRendererFrontend::getRenderer() { - return renderer.get(); -} - -} // namespace mbgl - diff --git a/test/src/mbgl/test/stub_renderer_frontend.hpp b/test/src/mbgl/test/stub_renderer_frontend.hpp deleted file mode 100644 index f6dd1d0472..0000000000 --- a/test/src/mbgl/test/stub_renderer_frontend.hpp +++ /dev/null @@ -1,44 +0,0 @@ - -#pragma once - -#include -#include -#include -#include -#include - -#include -#include - -namespace mbgl { - -class Renderer; -class View; - -class StubRendererFrontend : public RendererFrontend { -public: - // Calls the provided callback when it's time to render - using InvalidateCallback = std::function; - StubRendererFrontend(std::unique_ptr, InvalidateCallback); - - // Will render async - StubRendererFrontend(std::unique_ptr, View&); - - ~StubRendererFrontend() override; - - void reset() override; - - void setObserver(RendererObserver&) override; - - void update(std::shared_ptr) override; - void render(View& view); - - Renderer* getRenderer(); - -private: - std::unique_ptr renderer; - std::shared_ptr updateParameters; - util::AsyncTask asyncInvalidate; -}; - -} // namespace mbgl diff --git a/test/src/mbgl/test/util.cpp b/test/src/mbgl/test/util.cpp index 0b1034e315..028a0a9d51 100644 --- a/test/src/mbgl/test/util.cpp +++ b/test/src/mbgl/test/util.cpp @@ -1,12 +1,8 @@ #include -#include -#include #include #include #include -#include -#include #include @@ -98,19 +94,6 @@ Server::~Server() { } } -PremultipliedImage render(Map& map, OffscreenView& view) { - PremultipliedImage result; - map.renderStill([&](std::exception_ptr) { - result = view.readStillImage(); - }); - - while (!result.valid()) { - util::RunLoop::Get()->runOnce(); - } - - return result; -} - void checkImage(const std::string& base, const PremultipliedImage& actual, double imageThreshold, diff --git a/test/src/mbgl/test/util.hpp b/test/src/mbgl/test/util.hpp index 9c015f1641..7a8d78897e 100644 --- a/test/src/mbgl/test/util.hpp +++ b/test/src/mbgl/test/util.hpp @@ -54,11 +54,6 @@ #include namespace mbgl { - -class Map; -class OffscreenView; -class HeadlessDisplay; - namespace test { class Server { @@ -70,8 +65,6 @@ private: int fd = -1; }; -PremultipliedImage render(Map&, OffscreenView&); - void checkImage(const std::string& base, const PremultipliedImage& actual, double imageThreshold = 0, diff --git a/test/util/memory.test.cpp b/test/util/memory.test.cpp index ad7982ce57..54763cd9db 100644 --- a/test/util/memory.test.cpp +++ b/test/util/memory.test.cpp @@ -3,15 +3,11 @@ #include #include -#include -#include -#include +#include #include #include #include #include -#include -#include #include #include @@ -38,9 +34,6 @@ public: } util::RunLoop runLoop; - HeadlessBackend backend; - BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 512, 512 } }; StubFileSource fileSource; ThreadPool threadPool { 4 }; @@ -77,30 +70,25 @@ TEST(Memory, Vector) { MemoryTest test; float ratio { 2 }; - StubRendererFrontend rendererFrontend { - std::make_unique(test.backend, ratio, test.fileSource, test.threadPool), - test.view }; - Map map(rendererFrontend, MapObserver::nullObserver(), { 256, 256 }, ratio, test.fileSource, + HeadlessFrontend frontend { { 256, 256 }, ratio, test.fileSource, test.threadPool }; + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), ratio, test.fileSource, test.threadPool, MapMode::Still); map.setZoom(16); // more map features map.getStyle().loadURL("mapbox://streets"); - test::render(map, test.view); + frontend.render(map); } TEST(Memory, Raster) { MemoryTest test; float ratio { 2 }; - StubRendererFrontend rendererFrontend { - std::make_unique(test.backend, ratio, test.fileSource, test.threadPool), - test.view }; - - Map map(rendererFrontend, MapObserver::nullObserver(), { 256, 256 }, ratio, test.fileSource, + HeadlessFrontend frontend { { 256, 256 }, ratio, test.fileSource, test.threadPool }; + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), ratio, test.fileSource, test.threadPool, MapMode::Still); map.getStyle().loadURL("mapbox://satellite"); - test::render(map, test.view); + frontend.render(map); } /** @@ -127,57 +115,47 @@ TEST(Memory, Footprint) { if (!shouldRunFootprint()) { return; } - + MemoryTest test; - float ratio { 2 }; - auto renderMap = [&](Map& map, const char* style){ - map.setZoom(16); - map.getStyle().loadURL(style); - test::render(map, test.view); + class FrontendAndMap { + public: + FrontendAndMap(MemoryTest& test_, const char* style) + : frontend(Size{ 256, 256 }, 2, test_.fileSource, test_.threadPool) + , map(frontend, MapObserver::nullObserver(), frontend.getSize(), 2, test_.fileSource, test_.threadPool, MapMode::Still) { + map.setZoom(16); + map.getStyle().loadURL(style); + frontend.render(map); + } + + HeadlessFrontend frontend; + Map map; }; // Warm up buffers and cache. for (unsigned i = 0; i < 10; ++i) { - StubRendererFrontend rendererFrontend { - std::make_unique(test.backend, ratio, test.fileSource, test.threadPool), - test.view }; - Map map(rendererFrontend, MapObserver::nullObserver(), { 256, 256 }, ratio, test.fileSource, - test.threadPool, MapMode::Still); - renderMap(map, "mapbox://streets"); - renderMap(map, "mapbox://satellite"); - }; + FrontendAndMap(test, "mapbox://streets"); + FrontendAndMap(test, "mapbox://satellite"); + } // Process close callbacks, mostly needed by // libuv runloop. test.runLoop.runOnce(); - std::vector, std::unique_ptr>> maps; + std::vector> maps; unsigned runs = 15; long vectorInitialRSS = mbgl::test::getCurrentRSS(); for (unsigned i = 0; i < runs; ++i) { - auto frontend = std::make_unique( - std::make_unique(test.backend, ratio, test.fileSource, test.threadPool), test.view); - auto vector = std::make_unique(*frontend, MapObserver::nullObserver(), - Size{ 256, 256 }, ratio, test.fileSource, - test.threadPool, MapMode::Still); - renderMap(*vector, "mapbox://streets"); - maps.push_back({std::move(vector), std::move(frontend)}); - }; + maps.emplace_back(std::make_unique(test, "mapbox://streets")); + } double vectorFootprint = (mbgl::test::getCurrentRSS() - vectorInitialRSS) / double(runs); long rasterInitialRSS = mbgl::test::getCurrentRSS(); for (unsigned i = 0; i < runs; ++i) { - auto frontend = std::make_unique( - std::make_unique(test.backend, ratio, test.fileSource, test.threadPool), test.view); - auto raster = std::make_unique(*frontend, MapObserver::nullObserver(), - Size{ 256, 256 }, ratio, test.fileSource, - test.threadPool, MapMode::Still); - renderMap(*raster, "mapbox://satellite"); - maps.push_back({std::move(raster), std::move(frontend)}); - }; + maps.emplace_back(std::make_unique(test, "mapbox://satellite")); + } double rasterFootprint = (mbgl::test::getCurrentRSS() - rasterInitialRSS) / double(runs); diff --git a/test/util/offscreen_texture.test.cpp b/test/util/offscreen_texture.test.cpp index d4efd75689..09c940c4c3 100644 --- a/test/util/offscreen_texture.test.cpp +++ b/test/util/offscreen_texture.test.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include @@ -11,20 +10,19 @@ using namespace mbgl; TEST(OffscreenTexture, EmptyRed) { - HeadlessBackend backend; + HeadlessBackend backend({ 512, 256 }); BackendScope scope { backend }; - OffscreenView view(backend.getContext(), { 512, 256 }); - // Scissor test shouldn't leak after OffscreenView::bind(). + // Scissor test shouldn't leak after HeadlessBackend::bind(). MBGL_CHECK_ERROR(glScissor(64, 64, 128, 128)); backend.getContext().scissorTest.setCurrentValue(true); - view.bind(); + backend.bind(); MBGL_CHECK_ERROR(glClearColor(1.0f, 0.0f, 0.0f, 1.0f)); MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT)); - auto image = view.readStillImage(); + auto image = backend.readStillImage(); test::checkImage("test/fixtures/offscreen_texture/empty-red", image, 0, 0); } @@ -74,7 +72,7 @@ struct Buffer { TEST(OffscreenTexture, RenderToTexture) { - HeadlessBackend backend; + HeadlessBackend backend({ 512, 256 }); BackendScope scope { backend }; auto& context = backend.getContext(); @@ -124,8 +122,7 @@ void main() { Buffer triangleBuffer({ 0, 0.5, 0.5, -0.5, -0.5, -0.5 }); Buffer viewportBuffer({ -1, -1, 1, -1, -1, 1, 1, 1 }); - OffscreenView view(context, { 512, 256 }); - view.bind(); + backend.bind(); // First, draw red to the bound FBO. context.clear(Color::red(), {}, {}); @@ -153,9 +150,9 @@ void main() { test::checkImage("test/fixtures/offscreen_texture/render-to-texture", image, 0, 0); // Now reset the FBO back to normal and retrieve the original (restored) framebuffer. - view.bind(); + backend.bind(); - image = view.readStillImage(); + image = backend.readStillImage(); test::checkImage("test/fixtures/offscreen_texture/render-to-fbo", image, 0, 0); // Now, composite the Framebuffer texture we've rendered to onto the main FBO. @@ -168,6 +165,6 @@ void main() { glVertexAttribPointer(compositeShader.a_pos, 2, GL_FLOAT, GL_FALSE, 0, nullptr)); MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); - image = view.readStillImage(); + image = backend.readStillImage(); test::checkImage("test/fixtures/offscreen_texture/render-to-fbo-composited", image, 0, 0.1); } -- cgit v1.2.1