diff options
| author | 2015-12-07 10:01:38 -0800 | |
|---|---|---|
| committer | 2015-12-07 16:41:35 -0800 | |
| commit | 27e58b4f54d693ff1db7ab2edb5d47ca296c1278 (patch) | |
| tree | c53dba1d814cba2ac29c4a1614381883cdaa35bd | |
| parent | 1daf35db0fa05bf579e41aa62ee8a4478af182ff (diff) | |
Build hwui test scenes as common test code
And start using them in other non-macrobench tests
Change-Id: If155b531f3c89f97491001c06d1996df527b9f85
18 files changed, 148 insertions, 82 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index d98497bc046b..0d1ee46712ee 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -90,6 +90,9 @@ hwui_src_files := \ protos/hwui.proto hwui_test_common_src_files := \ + $(call all-cpp-files-under, tests/common/scenes) \ + tests/common/TestContext.cpp \ + tests/common/TestScene.cpp \ tests/common/TestUtils.cpp hwui_cflags := \ @@ -259,12 +262,9 @@ LOCAL_WHOLE_STATIC_LIBRARIES := libhwui_static LOCAL_SRC_FILES += \ $(hwui_test_common_src_files) \ - tests/macrobench/TestContext.cpp \ tests/macrobench/TestSceneRunner.cpp \ tests/macrobench/main.cpp -LOCAL_SRC_FILES += $(call all-cpp-files-under, tests/common/scenes) - include $(BUILD_EXECUTABLE) # ------------------------ diff --git a/libs/hwui/tests/macrobench/TestContext.cpp b/libs/hwui/tests/common/TestContext.cpp index ba763a8def62..146e735839d1 100644 --- a/libs/hwui/tests/macrobench/TestContext.cpp +++ b/libs/hwui/tests/common/TestContext.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "TestContext.h" +#include "tests/common/TestContext.h" namespace android { namespace uirenderer { diff --git a/libs/hwui/tests/macrobench/TestContext.h b/libs/hwui/tests/common/TestContext.h index 2bbe5dffd9b8..2bbe5dffd9b8 100644 --- a/libs/hwui/tests/macrobench/TestContext.h +++ b/libs/hwui/tests/common/TestContext.h diff --git a/libs/hwui/tests/macrobench/Benchmark.h b/libs/hwui/tests/common/TestScene.cpp index aad8eb3716a6..02bcd4768a65 100644 --- a/libs/hwui/tests/macrobench/Benchmark.h +++ b/libs/hwui/tests/common/TestScene.cpp @@ -13,49 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef TESTS_BENCHMARK_H -#define TESTS_BENCHMARK_H #include "tests/common/TestScene.h" -#include <string> -#include <vector> - namespace android { namespace uirenderer { +namespace test { -struct BenchmarkOptions { - int count; -}; - -typedef test::TestScene* (*CreateScene)(const BenchmarkOptions&); - -template <class T> -test::TestScene* simpleCreateScene(const BenchmarkOptions&) { - return new T(); +// Not a static global because we need to force the map to be constructed +// before we try to add things to it. +std::unordered_map<std::string, TestScene::Info>& TestScene::testMap() { + static std::unordered_map<std::string, TestScene::Info> testMap; + return testMap; } -struct BenchmarkInfo { - std::string name; - std::string description; - CreateScene createScene; -}; - -class Benchmark { -public: - Benchmark(const BenchmarkInfo& info) { - registerBenchmark(info); - } - -private: - Benchmark() = delete; - Benchmark(const Benchmark&) = delete; - Benchmark& operator=(const Benchmark&) = delete; - - static void registerBenchmark(const BenchmarkInfo& info); -}; +void TestScene::registerScene(const TestScene::Info& info) { + testMap()[info.name] = info; +} +} /* namespace test */ } /* namespace uirenderer */ } /* namespace android */ - -#endif /* TESTS_BENCHMARK_H */ diff --git a/libs/hwui/tests/common/TestScene.h b/libs/hwui/tests/common/TestScene.h index b5d8954652a3..df8d194f641b 100644 --- a/libs/hwui/tests/common/TestScene.h +++ b/libs/hwui/tests/common/TestScene.h @@ -16,6 +16,9 @@ #ifndef TESTS_TESTSCENE_H #define TESTS_TESTSCENE_H +#include <string> +#include <unordered_map> + namespace android { namespace uirenderer { class RenderNode; @@ -32,9 +35,40 @@ namespace test { class TestScene { public: + struct Options { + int count = 0; + }; + + template <class T> + static test::TestScene* simpleCreateScene(const TestScene::Options&) { + return new T(); + } + + typedef test::TestScene* (*CreateScene)(const TestScene::Options&); + + struct Info { + std::string name; + std::string description; + CreateScene createScene; + }; + + class Registrar { + public: + Registrar(const TestScene::Info& info) { + TestScene::registerScene(info); + } + private: + Registrar() = delete; + Registrar(const Registrar&) = delete; + Registrar& operator=(const Registrar&) = delete; + }; + virtual ~TestScene() {} virtual void createContent(int width, int height, TestCanvas& renderer) = 0; virtual void doFrame(int frameNr) = 0; + + static std::unordered_map<std::string, Info>& testMap(); + static void registerScene(const Info& info); }; } // namespace test diff --git a/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp b/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp index e316eca79be8..c212df4f978d 100644 --- a/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp +++ b/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp @@ -18,11 +18,11 @@ class HwLayerAnimation; -static Benchmark _HwLayer(BenchmarkInfo{ +static TestScene::Registrar _HwLayer(TestScene::Info{ "hwlayer", "A nested pair of nodes with LAYER_TYPE_HARDWARE set on each. " "Tests the hardware layer codepath.", - simpleCreateScene<HwLayerAnimation> + TestScene::simpleCreateScene<HwLayerAnimation> }); class HwLayerAnimation : public TestScene { diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp index 6c64a327013e..43e247e68bc0 100644 --- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp +++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp @@ -21,11 +21,11 @@ class ListViewAnimation; -static Benchmark _ListView(BenchmarkInfo{ +static TestScene::Registrar _ListView(TestScene::Info{ "listview", "A mock ListView of scrolling content. Doesn't re-bind/re-record views as they are recycled, so" "won't upload much content (either glyphs, or bitmaps).", - simpleCreateScene<ListViewAnimation> + TestScene::simpleCreateScene<ListViewAnimation> }); class ListViewAnimation : public TestScene { diff --git a/libs/hwui/tests/common/scenes/OvalAnimation.cpp b/libs/hwui/tests/common/scenes/OvalAnimation.cpp index 936aba184c88..082c6287e86f 100644 --- a/libs/hwui/tests/common/scenes/OvalAnimation.cpp +++ b/libs/hwui/tests/common/scenes/OvalAnimation.cpp @@ -18,10 +18,10 @@ class OvalAnimation; -static Benchmark _Oval(BenchmarkInfo{ +static TestScene::Registrar _Oval(TestScene::Info{ "oval", "Draws 1 oval.", - simpleCreateScene<OvalAnimation> + TestScene::simpleCreateScene<OvalAnimation> }); class OvalAnimation : public TestScene { diff --git a/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp b/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp index c31ddd1d531b..84265a4774a5 100644 --- a/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp +++ b/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp @@ -18,12 +18,12 @@ class PartialDamageAnimation; -static Benchmark _PartialDamage(BenchmarkInfo{ +static TestScene::Registrar _PartialDamage(TestScene::Info{ "partialdamage", "Tests the partial invalidation path. Draws a grid of rects and animates 1 " "of them, should be low CPU & GPU load if EGL_EXT_buffer_age or " "EGL_KHR_partial_update is supported by the device & are enabled in hwui.", - simpleCreateScene<PartialDamageAnimation> + TestScene::simpleCreateScene<PartialDamageAnimation> }); class PartialDamageAnimation : public TestScene { diff --git a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp index 5d4ef9663d34..6509edd4077f 100644 --- a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp +++ b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp @@ -19,11 +19,11 @@ class RecentsAnimation; -static Benchmark _Recents(BenchmarkInfo{ +static TestScene::Registrar _Recents(TestScene::Info{ "recents", "A recents-like scrolling list of textures. " "Consists of updating a texture every frame", - simpleCreateScene<RecentsAnimation> + TestScene::simpleCreateScene<RecentsAnimation> }); class RecentsAnimation : public TestScene { diff --git a/libs/hwui/tests/common/scenes/RectGridAnimation.cpp b/libs/hwui/tests/common/scenes/RectGridAnimation.cpp index a1f04d67c785..a9293ab244dd 100644 --- a/libs/hwui/tests/common/scenes/RectGridAnimation.cpp +++ b/libs/hwui/tests/common/scenes/RectGridAnimation.cpp @@ -19,11 +19,11 @@ class RectGridAnimation; -static Benchmark _RectGrid(BenchmarkInfo{ +static TestScene::Registrar _RectGrid(TestScene::Info{ "rectgrid", "A dense grid of 1x1 rects that should visually look like a single rect. " "Low CPU/GPU load.", - simpleCreateScene<RectGridAnimation> + TestScene::simpleCreateScene<RectGridAnimation> }); class RectGridAnimation : public TestScene { diff --git a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp index c73e97ba003c..78fcd8bf30ac 100644 --- a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp +++ b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp @@ -18,11 +18,11 @@ class SaveLayerAnimation; -static Benchmark _SaveLayer(BenchmarkInfo{ +static TestScene::Registrar _SaveLayer(TestScene::Info{ "savelayer", "A nested pair of clipped saveLayer operations. " "Tests the clipped saveLayer codepath. Draws content into offscreen buffers and back again.", - simpleCreateScene<SaveLayerAnimation> + TestScene::simpleCreateScene<SaveLayerAnimation> }); class SaveLayerAnimation : public TestScene { diff --git a/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp b/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp index 26c86aa6f9d5..d3249b8f585a 100644 --- a/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp +++ b/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp @@ -18,11 +18,11 @@ class ShadowGrid2Animation; -static Benchmark _ShadowGrid2(BenchmarkInfo{ +static TestScene::Registrar _ShadowGrid2(TestScene::Info{ "shadowgrid2", "A dense grid of rounded rects that cast a shadow. This is a higher CPU load " "variant of shadowgrid. Very high CPU load, high GPU load.", - simpleCreateScene<ShadowGrid2Animation> + TestScene::simpleCreateScene<ShadowGrid2Animation> }); class ShadowGrid2Animation : public TestScene { diff --git a/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp b/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp index ee3c590c4e0d..5ffedf09bc70 100644 --- a/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp +++ b/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp @@ -18,11 +18,11 @@ class ShadowGridAnimation; -static Benchmark _ShadowGrid(BenchmarkInfo{ +static TestScene::Registrar _ShadowGrid(TestScene::Info{ "shadowgrid", "A grid of rounded rects that cast a shadow. Simplified scenario of an " "Android TV-style launcher interface. High CPU/GPU load.", - simpleCreateScene<ShadowGridAnimation> + TestScene::simpleCreateScene<ShadowGridAnimation> }); class ShadowGridAnimation : public TestScene { diff --git a/libs/hwui/tests/common/scenes/TestSceneBase.h b/libs/hwui/tests/common/scenes/TestSceneBase.h index 8a2414971515..ac781243c25e 100644 --- a/libs/hwui/tests/common/scenes/TestSceneBase.h +++ b/libs/hwui/tests/common/scenes/TestSceneBase.h @@ -19,8 +19,7 @@ #include "DisplayListCanvas.h" #include "RecordingCanvas.h" #include "RenderNode.h" -#include "tests/macrobench/Benchmark.h" -#include "tests/macrobench/TestContext.h" +#include "tests/common/TestContext.h" #include "tests/common/TestScene.h" #include "tests/common/TestUtils.h" diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp index 1e1c6a1e318a..82612206cac8 100644 --- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp +++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp @@ -15,9 +15,9 @@ */ #include "AnimationContext.h" -#include "Benchmark.h" #include "RenderNode.h" -#include "TestContext.h" +#include "tests/common/TestContext.h" +#include "tests/common/TestScene.h" #include "tests/common/scenes/TestSceneBase.h" #include "renderthread/RenderProxy.h" #include "renderthread/RenderTask.h" @@ -38,7 +38,7 @@ public: } }; -void run(const BenchmarkInfo& info, const BenchmarkOptions& opts) { +void run(const TestScene::Info& info, const TestScene::Options& opts) { // Switch to the real display gDisplay = getBuiltInDisplay(); diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp index 48566e8f6ecd..619713c58c9a 100644 --- a/libs/hwui/tests/macrobench/main.cpp +++ b/libs/hwui/tests/macrobench/main.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "Benchmark.h" +#include "tests/common/TestScene.h" #include "protos/hwui.pb.h" @@ -27,23 +27,13 @@ using namespace android; using namespace android::uirenderer; - -// Not a static global because we need to force the map to be constructed -// before we try to add things to it. -std::unordered_map<std::string, BenchmarkInfo>& testMap() { - static std::unordered_map<std::string, BenchmarkInfo> testMap; - return testMap; -} - -void Benchmark::registerBenchmark(const BenchmarkInfo& info) { - testMap()[info.name] = info; -} +using namespace android::uirenderer::test; static int gFrameCount = 150; static int gRepeatCount = 1; -static std::vector<BenchmarkInfo> gRunTests; +static std::vector<TestScene::Info> gRunTests; -void run(const BenchmarkInfo& info, const BenchmarkOptions& opts); +void run(const TestScene::Info& info, const TestScene::Options& opts); static void printHelp() { printf("\ @@ -59,7 +49,7 @@ OPTIONS:\n\ static void listTests() { printf("Tests: \n"); - for (auto&& test : testMap()) { + for (auto&& test : TestScene::testMap()) { auto&& info = test.second; const char* col1 = info.name.c_str(); int dlen = info.description.length(); @@ -168,8 +158,8 @@ void parseOptions(int argc, char* argv[]) { if (optind < argc) { do { const char* test = argv[optind++]; - auto pos = testMap().find(test); - if (pos == testMap().end()) { + auto pos = TestScene::testMap().find(test); + if (pos == TestScene::testMap().end()) { fprintf(stderr, "Unknown test '%s'\n", test); exit(EXIT_FAILURE); } else { @@ -177,14 +167,14 @@ void parseOptions(int argc, char* argv[]) { } } while (optind < argc); } else { - gRunTests.push_back(testMap()["shadowgrid"]); + gRunTests.push_back(TestScene::testMap()["shadowgrid"]); } } int main(int argc, char* argv[]) { parseOptions(argc, argv); - BenchmarkOptions opts; + TestScene::Options opts; opts.count = gFrameCount; for (int i = 0; i < gRepeatCount; i++) { for (auto&& test : gRunTests) { diff --git a/libs/hwui/tests/microbench/OpReordererBench.cpp b/libs/hwui/tests/microbench/OpReordererBench.cpp index ac2b15cc620a..6bfe5a9a1028 100644 --- a/libs/hwui/tests/microbench/OpReordererBench.cpp +++ b/libs/hwui/tests/microbench/OpReordererBench.cpp @@ -23,6 +23,8 @@ #include "OpReorderer.h" #include "RecordedOp.h" #include "RecordingCanvas.h" +#include "tests/common/TestContext.h" +#include "tests/common/TestScene.h" #include "tests/common/TestUtils.h" #include "Vector.h" #include "tests/microbench/MicroBench.h" @@ -31,6 +33,8 @@ using namespace android; using namespace android::uirenderer; +using namespace android::uirenderer::renderthread; +using namespace android::uirenderer::test; const LayerUpdateQueue sEmptyLayerUpdateQueue; const Vector3 sLightCenter = {100, 100, 100}; @@ -71,7 +75,7 @@ void BM_OpReorderer_defer::Run(int iters) { BENCHMARK_NO_ARG(BM_OpReorderer_deferAndRender); void BM_OpReorderer_deferAndRender::Run(int iters) { - TestUtils::runOnRenderThread([this, iters](renderthread::RenderThread& thread) { + TestUtils::runOnRenderThread([this, iters](RenderThread& thread) { auto nodes = createTestNodeList(); BakedOpRenderer::LightInfo lightInfo = {50.0f, 128, 128 }; @@ -90,3 +94,67 @@ void BM_OpReorderer_deferAndRender::Run(int iters) { StopBenchmarkTiming(); }); } + +static std::vector<sp<RenderNode>> getSyncedSceneNodes(const char* sceneName) { + gDisplay = getBuiltInDisplay(); // switch to real display if present + + TestContext testContext; + TestScene::Options opts; + std::unique_ptr<TestScene> scene(TestScene::testMap()[sceneName].createScene(opts)); + + sp<RenderNode> rootNode = TestUtils::createNode(0, 0, gDisplay.w, gDisplay.h, + [&scene](RenderProperties& props, TestCanvas& canvas) { + scene->createContent(gDisplay.w, gDisplay.h, canvas); + }); + + TestUtils::syncHierarchyPropertiesAndDisplayList(rootNode); + std::vector<sp<RenderNode>> nodes; + nodes.emplace_back(rootNode); + return nodes; +} + +static void benchDeferScene(testing::Benchmark& benchmark, int iters, const char* sceneName) { + auto nodes = getSyncedSceneNodes(sceneName); + benchmark.StartBenchmarkTiming(); + for (int i = 0; i < iters; i++) { + OpReorderer reorderer(sEmptyLayerUpdateQueue, + SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, + nodes, sLightCenter); + MicroBench::DoNotOptimize(&reorderer); + } + benchmark.StopBenchmarkTiming(); +} + +static void benchDeferAndRenderScene(testing::Benchmark& benchmark, + int iters, const char* sceneName) { + TestUtils::runOnRenderThread([&benchmark, iters, sceneName](RenderThread& thread) { + auto nodes = getSyncedSceneNodes(sceneName); + BakedOpRenderer::LightInfo lightInfo = {50.0f, 128, 128 }; // TODO! + + RenderState& renderState = thread.renderState(); + Caches& caches = Caches::getInstance(); + + benchmark.StartBenchmarkTiming(); + for (int i = 0; i < iters; i++) { + OpReorderer reorderer(sEmptyLayerUpdateQueue, + SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, + nodes, sLightCenter); + + BakedOpRenderer renderer(caches, renderState, true, lightInfo); + reorderer.replayBakedOps<BakedOpDispatcher>(renderer); + MicroBench::DoNotOptimize(&renderer); + } + benchmark.StopBenchmarkTiming(); + }); +} + +BENCHMARK_NO_ARG(BM_OpReorderer_listview_defer); +void BM_OpReorderer_listview_defer::Run(int iters) { + benchDeferScene(*this, iters, "listview"); +} + +BENCHMARK_NO_ARG(BM_OpReorderer_listview_deferAndRender); +void BM_OpReorderer_listview_deferAndRender::Run(int iters) { + benchDeferAndRenderScene(*this, iters, "listview"); +} + |