OSDN Git Service

Build hwui test scenes as common test code
authorChris Craik <ccraik@google.com>
Mon, 7 Dec 2015 18:01:38 +0000 (10:01 -0800)
committerChris Craik <ccraik@google.com>
Tue, 8 Dec 2015 00:41:35 +0000 (16:41 -0800)
And start using them in other non-macrobench tests

Change-Id: If155b531f3c89f97491001c06d1996df527b9f85

18 files changed:
libs/hwui/Android.mk
libs/hwui/tests/common/TestContext.cpp [moved from libs/hwui/tests/macrobench/TestContext.cpp with 98% similarity]
libs/hwui/tests/common/TestContext.h [moved from libs/hwui/tests/macrobench/TestContext.h with 100% similarity]
libs/hwui/tests/common/TestScene.cpp [moved from libs/hwui/tests/macrobench/Benchmark.h with 50% similarity]
libs/hwui/tests/common/TestScene.h
libs/hwui/tests/common/scenes/HwLayerAnimation.cpp
libs/hwui/tests/common/scenes/ListViewAnimation.cpp
libs/hwui/tests/common/scenes/OvalAnimation.cpp
libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp
libs/hwui/tests/common/scenes/RecentsAnimation.cpp
libs/hwui/tests/common/scenes/RectGridAnimation.cpp
libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp
libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp
libs/hwui/tests/common/scenes/TestSceneBase.h
libs/hwui/tests/macrobench/TestSceneRunner.cpp
libs/hwui/tests/macrobench/main.cpp
libs/hwui/tests/microbench/OpReordererBench.cpp

index d98497b..0d1ee46 100644 (file)
@@ -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)
 
 # ------------------------
similarity index 98%
rename from libs/hwui/tests/macrobench/TestContext.cpp
rename to libs/hwui/tests/common/TestContext.cpp
index ba763a8..146e735 100644 (file)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "TestContext.h"
+#include "tests/common/TestContext.h"
 
 namespace android {
 namespace uirenderer {
similarity index 50%
rename from libs/hwui/tests/macrobench/Benchmark.h
rename to libs/hwui/tests/common/TestScene.cpp
index aad8eb3..02bcd47 100644 (file)
  * 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 */
index b5d8954..df8d194 100644 (file)
@@ -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
index e316eca..c212df4 100644 (file)
 
 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 {
index 6c64a32..43e247e 100644 (file)
 
 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 {
index 936aba1..082c628 100644 (file)
 
 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 {
index c31ddd1..84265a4 100644 (file)
 
 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 {
index 5d4ef96..6509edd 100644 (file)
 
 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 {
index a1f04d6..a9293ab 100644 (file)
 
 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 {
index c73e97b..78fcd8b 100644 (file)
 
 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 {
index 26c86aa..d3249b8 100644 (file)
 
 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 {
index ee3c590..5ffedf0 100644 (file)
 
 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 {
index 8a24149..ac78124 100644 (file)
@@ -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"
 
index 1e1c6a1..8261220 100644 (file)
@@ -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();
 
index 48566e8..619713c 100644 (file)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "Benchmark.h"
+#include "tests/common/TestScene.h"
 
 #include "protos/hwui.pb.h"
 
 
 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) {
index ac2b15c..6bfe5a9 100644 (file)
@@ -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");
+}
+