diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index cc0943f..eaade34 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -209,6 +209,7 @@
 
 LOCAL_SRC_FILES += \
     tests/TestContext.cpp \
+    tests/TreeContentAnimation.cpp \
     tests/main.cpp
 
 include $(BUILD_EXECUTABLE)
diff --git a/libs/hwui/tests/Benchmark.h b/libs/hwui/tests/Benchmark.h
new file mode 100644
index 0000000..e16310e
--- /dev/null
+++ b/libs/hwui/tests/Benchmark.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef TESTS_BENCHMARK_H
+#define TESTS_BENCHMARK_H
+
+#include <string>
+#include <vector>
+
+namespace android {
+namespace uirenderer {
+
+struct BenchmarkOptions {
+    int count;
+};
+
+typedef void (*BenchmarkFunctor)(const BenchmarkOptions&);
+
+struct BenchmarkInfo {
+    std::string name;
+    std::string description;
+    BenchmarkFunctor functor;
+};
+
+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);
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* TESTS_BENCHMARK_H */
diff --git a/libs/hwui/tests/TestContext.cpp b/libs/hwui/tests/TestContext.cpp
index cebe765..ba763a8 100644
--- a/libs/hwui/tests/TestContext.cpp
+++ b/libs/hwui/tests/TestContext.cpp
@@ -22,16 +22,35 @@
 
 static const int IDENT_DISPLAYEVENT = 1;
 
-static DisplayInfo getBuiltInDisplay() {
+static android::DisplayInfo DUMMY_DISPLAY {
+    1080, //w
+    1920, //h
+    320.0, // xdpi
+    320.0, // ydpi
+    60.0, // fps
+    2.0, // density
+    0, // orientation
+    false, // secure?
+    0, // appVsyncOffset
+    0, // presentationDeadline
+    0, // colorTransform
+};
+
+DisplayInfo getBuiltInDisplay() {
+#if !HWUI_NULL_GPU
     DisplayInfo display;
     sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
             ISurfaceComposer::eDisplayIdMain));
     status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &display);
     LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n");
     return display;
+#else
+    return DUMMY_DISPLAY;
+#endif
 }
 
-android::DisplayInfo gDisplay = getBuiltInDisplay();
+// Initialize to a dummy default
+android::DisplayInfo gDisplay = DUMMY_DISPLAY;
 
 TestContext::TestContext() {
     mLooper = new Looper(true);
diff --git a/libs/hwui/tests/TestContext.h b/libs/hwui/tests/TestContext.h
index 7b30fc1..2bbe5df 100644
--- a/libs/hwui/tests/TestContext.h
+++ b/libs/hwui/tests/TestContext.h
@@ -32,6 +32,8 @@
 extern DisplayInfo gDisplay;
 #define dp(x) ((x) * android::uirenderer::test::gDisplay.density)
 
+DisplayInfo getBuiltInDisplay();
+
 class TestContext {
 public:
     TestContext();
diff --git a/libs/hwui/tests/TreeContentAnimation.cpp b/libs/hwui/tests/TreeContentAnimation.cpp
new file mode 100644
index 0000000..a59261c
--- /dev/null
+++ b/libs/hwui/tests/TreeContentAnimation.cpp
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cutils/log.h>
+#include <gui/Surface.h>
+#include <ui/PixelFormat.h>
+
+#include <AnimationContext.h>
+#include <DisplayListCanvas.h>
+#include <RenderNode.h>
+#include <renderthread/RenderProxy.h>
+#include <renderthread/RenderTask.h>
+
+#include "Benchmark.h"
+#include "TestContext.h"
+
+#include "protos/hwui.pb.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <vector>
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+using namespace android::uirenderer::test;
+
+class ContextFactory : public IContextFactory {
+public:
+    virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {
+        return new AnimationContext(clock);
+    }
+};
+
+static DisplayListCanvas* startRecording(RenderNode* node) {
+    DisplayListCanvas* renderer = new DisplayListCanvas(
+            node->stagingProperties().getWidth(), node->stagingProperties().getHeight());
+    return renderer;
+}
+
+static void endRecording(DisplayListCanvas* renderer, RenderNode* node) {
+    node->setStagingDisplayList(renderer->finishRecording());
+    delete renderer;
+}
+
+class TreeContentAnimation {
+public:
+    virtual ~TreeContentAnimation() {}
+    int frameCount = 150;
+    virtual int getFrameCount() { return frameCount; }
+    virtual void setFrameCount(int fc) {
+        if (fc > 0) {
+            frameCount = fc;
+        }
+    }
+    virtual void createContent(int width, int height, DisplayListCanvas* renderer) = 0;
+    virtual void doFrame(int frameNr) = 0;
+
+    template <class T>
+    static void run(const BenchmarkOptions& opts) {
+        // Switch to the real display
+        gDisplay = getBuiltInDisplay();
+
+        T animation;
+        animation.setFrameCount(opts.count);
+
+        TestContext testContext;
+
+        // create the native surface
+        const int width = gDisplay.w;
+        const int height = gDisplay.h;
+        sp<Surface> surface = testContext.surface();
+
+        RenderNode* rootNode = new RenderNode();
+        rootNode->incStrong(nullptr);
+        rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height);
+        rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+        rootNode->mutateStagingProperties().setClipToBounds(false);
+        rootNode->setPropertyFieldsDirty(RenderNode::GENERIC);
+
+        ContextFactory factory;
+        std::unique_ptr<RenderProxy> proxy(new RenderProxy(false, rootNode, &factory));
+        proxy->loadSystemProperties();
+        proxy->initialize(surface);
+        float lightX = width / 2.0;
+        proxy->setup(width, height, dp(800.0f), 255 * 0.075, 255 * 0.15);
+        proxy->setLightCenter((Vector3){lightX, dp(-200.0f), dp(800.0f)});
+
+        android::uirenderer::Rect DUMMY;
+
+        DisplayListCanvas* renderer = startRecording(rootNode);
+        animation.createContent(width, height, renderer);
+        endRecording(renderer, rootNode);
+
+        // Do a few cold runs then reset the stats so that the caches are all hot
+        for (int i = 0; i < 3; i++) {
+            testContext.waitForVsync();
+            proxy->syncAndDrawFrame();
+        }
+        proxy->resetProfileInfo();
+
+        for (int i = 0; i < animation.getFrameCount(); i++) {
+            testContext.waitForVsync();
+
+            ATRACE_NAME("UI-Draw Frame");
+            nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
+            UiFrameInfoBuilder(proxy->frameInfo())
+                    .setVsync(vsync, vsync);
+            animation.doFrame(i);
+            proxy->syncAndDrawFrame();
+        }
+
+        proxy->dumpProfileInfo(STDOUT_FILENO, 0);
+        rootNode->decStrong(nullptr);
+    }
+};
+
+class ShadowGridAnimation : public TreeContentAnimation {
+public:
+    std::vector< sp<RenderNode> > cards;
+    void createContent(int width, int height, DisplayListCanvas* renderer) override {
+        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
+        renderer->insertReorderBarrier(true);
+
+        for (int x = dp(16); x < (width - dp(116)); x += dp(116)) {
+            for (int y = dp(16); y < (height - dp(116)); y += dp(116)) {
+                sp<RenderNode> card = createCard(x, y, dp(100), dp(100));
+                renderer->drawRenderNode(card.get());
+                cards.push_back(card);
+            }
+        }
+
+        renderer->insertReorderBarrier(false);
+    }
+    void doFrame(int frameNr) override {
+        int curFrame = frameNr % 150;
+        for (size_t ci = 0; ci < cards.size(); ci++) {
+            cards[ci]->mutateStagingProperties().setTranslationX(curFrame);
+            cards[ci]->mutateStagingProperties().setTranslationY(curFrame);
+            cards[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+        }
+    }
+private:
+    sp<RenderNode> createCard(int x, int y, int width, int height) {
+        sp<RenderNode> node = new RenderNode();
+        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
+        node->mutateStagingProperties().setElevation(dp(16));
+        node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1);
+        node->mutateStagingProperties().mutableOutline().setShouldClip(true);
+        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z);
+
+        DisplayListCanvas* renderer = startRecording(node.get());
+        renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode);
+        endRecording(renderer, node.get());
+        return node;
+    }
+};
+static Benchmark _ShadowGrid(BenchmarkInfo{
+    "shadowgrid",
+    "A grid of rounded rects that cast a shadow. Simplified scenario of an "
+    "Android TV-style launcher interface. High CPU/GPU load.",
+    TreeContentAnimation::run<ShadowGridAnimation>
+});
+
+class ShadowGrid2Animation : public TreeContentAnimation {
+public:
+    std::vector< sp<RenderNode> > cards;
+    void createContent(int width, int height, DisplayListCanvas* renderer) override {
+        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
+        renderer->insertReorderBarrier(true);
+
+        for (int x = dp(8); x < (width - dp(58)); x += dp(58)) {
+            for (int y = dp(8); y < (height - dp(58)); y += dp(58)) {
+                sp<RenderNode> card = createCard(x, y, dp(50), dp(50));
+                renderer->drawRenderNode(card.get());
+                cards.push_back(card);
+            }
+        }
+
+        renderer->insertReorderBarrier(false);
+    }
+    void doFrame(int frameNr) override {
+        int curFrame = frameNr % 150;
+        for (size_t ci = 0; ci < cards.size(); ci++) {
+            cards[ci]->mutateStagingProperties().setTranslationX(curFrame);
+            cards[ci]->mutateStagingProperties().setTranslationY(curFrame);
+            cards[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+        }
+    }
+private:
+    sp<RenderNode> createCard(int x, int y, int width, int height) {
+        sp<RenderNode> node = new RenderNode();
+        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
+        node->mutateStagingProperties().setElevation(dp(16));
+        node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(6), 1);
+        node->mutateStagingProperties().mutableOutline().setShouldClip(true);
+        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z);
+
+        DisplayListCanvas* renderer = startRecording(node.get());
+        renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode);
+        endRecording(renderer, node.get());
+        return node;
+    }
+};
+static Benchmark _ShadowGrid2(BenchmarkInfo{
+    "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.",
+    TreeContentAnimation::run<ShadowGrid2Animation>
+});
+
+class RectGridAnimation : public TreeContentAnimation {
+public:
+    sp<RenderNode> card;
+    void createContent(int width, int height, DisplayListCanvas* renderer) override {
+        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
+        renderer->insertReorderBarrier(true);
+
+        card = createCard(40, 40, 200, 200);
+        renderer->drawRenderNode(card.get());
+
+        renderer->insertReorderBarrier(false);
+    }
+    void doFrame(int frameNr) override {
+        int curFrame = frameNr % 150;
+        card->mutateStagingProperties().setTranslationX(curFrame);
+        card->mutateStagingProperties().setTranslationY(curFrame);
+        card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+    }
+private:
+    sp<RenderNode> createCard(int x, int y, int width, int height) {
+        sp<RenderNode> node = new RenderNode();
+        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
+        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+
+        DisplayListCanvas* renderer = startRecording(node.get());
+        renderer->drawColor(0xFFFF00FF, SkXfermode::kSrcOver_Mode);
+
+        SkRegion region;
+        for (int xOffset = 0; xOffset < width; xOffset+=2) {
+            for (int yOffset = 0; yOffset < height; yOffset+=2) {
+                region.op(xOffset, yOffset, xOffset + 1, yOffset + 1, SkRegion::kUnion_Op);
+            }
+        }
+
+        SkPaint paint;
+        paint.setColor(0xff00ffff);
+        renderer->drawRegion(region, paint);
+
+        endRecording(renderer, node.get());
+        return node;
+    }
+};
+static Benchmark _RectGrid(BenchmarkInfo{
+    "rectgrid",
+    "A dense grid of 1x1 rects that should visually look like a single rect. "
+    "Low CPU/GPU load.",
+    TreeContentAnimation::run<RectGridAnimation>
+});
+
+class OvalAnimation : public TreeContentAnimation {
+public:
+    sp<RenderNode> card;
+    void createContent(int width, int height, DisplayListCanvas* renderer) override {
+        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
+        renderer->insertReorderBarrier(true);
+
+        card = createCard(40, 40, 400, 400);
+        renderer->drawRenderNode(card.get());
+
+        renderer->insertReorderBarrier(false);
+    }
+
+    void doFrame(int frameNr) override {
+        int curFrame = frameNr % 150;
+        card->mutateStagingProperties().setTranslationX(curFrame);
+        card->mutateStagingProperties().setTranslationY(curFrame);
+        card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+    }
+private:
+    sp<RenderNode> createCard(int x, int y, int width, int height) {
+        sp<RenderNode> node = new RenderNode();
+        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
+        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+
+        DisplayListCanvas* renderer = startRecording(node.get());
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setColor(0xFF000000);
+        renderer->drawOval(0, 0, width, height, paint);
+
+        endRecording(renderer, node.get());
+        return node;
+    }
+};
+static Benchmark _Oval(BenchmarkInfo{
+    "oval",
+    "Draws 1 oval.",
+    TreeContentAnimation::run<OvalAnimation>
+});
+
+class PartialDamageTest : public TreeContentAnimation {
+public:
+    std::vector< sp<RenderNode> > cards;
+    void createContent(int width, int height, DisplayListCanvas* renderer) override {
+        static SkColor COLORS[] = {
+                0xFFF44336,
+                0xFF9C27B0,
+                0xFF2196F3,
+                0xFF4CAF50,
+        };
+
+        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
+
+        for (int x = dp(16); x < (width - dp(116)); x += dp(116)) {
+            for (int y = dp(16); y < (height - dp(116)); y += dp(116)) {
+                sp<RenderNode> card = createCard(x, y, dp(100), dp(100),
+                        COLORS[static_cast<int>((y / dp(116))) % 4]);
+                renderer->drawRenderNode(card.get());
+                cards.push_back(card);
+            }
+        }
+    }
+    void doFrame(int frameNr) override {
+        int curFrame = frameNr % 150;
+        cards[0]->mutateStagingProperties().setTranslationX(curFrame);
+        cards[0]->mutateStagingProperties().setTranslationY(curFrame);
+        cards[0]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+
+        DisplayListCanvas* renderer = startRecording(cards[0].get());
+        renderer->drawColor(interpolateColor(curFrame / 150.0f, 0xFFF44336, 0xFFF8BBD0),
+                SkXfermode::kSrcOver_Mode);
+        endRecording(renderer, cards[0].get());
+    }
+
+    static SkColor interpolateColor(float fraction, SkColor start, SkColor end) {
+        int startA = (start >> 24) & 0xff;
+        int startR = (start >> 16) & 0xff;
+        int startG = (start >> 8) & 0xff;
+        int startB = start & 0xff;
+
+        int endA = (end >> 24) & 0xff;
+        int endR = (end >> 16) & 0xff;
+        int endG = (end >> 8) & 0xff;
+        int endB = end & 0xff;
+
+        return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
+                (int)((startR + (int)(fraction * (endR - startR))) << 16) |
+                (int)((startG + (int)(fraction * (endG - startG))) << 8) |
+                (int)((startB + (int)(fraction * (endB - startB))));
+    }
+private:
+    sp<RenderNode> createCard(int x, int y, int width, int height, SkColor color) {
+        sp<RenderNode> node = new RenderNode();
+        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
+        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+
+        DisplayListCanvas* renderer = startRecording(node.get());
+        renderer->drawColor(color, SkXfermode::kSrcOver_Mode);
+        endRecording(renderer, node.get());
+        return node;
+    }
+};
+static Benchmark _PartialDamage(BenchmarkInfo{
+    "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.",
+    TreeContentAnimation::run<PartialDamageTest>
+});
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index f794507..aee84de 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -14,361 +14,34 @@
  * limitations under the License.
  */
 
-#include <cutils/log.h>
-#include <gui/Surface.h>
-#include <ui/PixelFormat.h>
-
-#include <AnimationContext.h>
-#include <DisplayListCanvas.h>
-#include <RenderNode.h>
-#include <renderthread/RenderProxy.h>
-#include <renderthread/RenderTask.h>
-
-#include "TestContext.h"
+#include "Benchmark.h"
 
 #include "protos/hwui.pb.h"
 
-#include <stdio.h>
-#include <unistd.h>
 #include <getopt.h>
+#include <stdio.h>
+#include <string>
+#include <unistd.h>
+#include <unordered_map>
 #include <vector>
 
 using namespace android;
 using namespace android::uirenderer;
-using namespace android::uirenderer::renderthread;
-using namespace android::uirenderer::test;
 
-class ContextFactory : public IContextFactory {
-public:
-    virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override {
-        return new AnimationContext(clock);
-    }
-};
-
-static DisplayListCanvas* startRecording(RenderNode* node) {
-    DisplayListCanvas* renderer = new DisplayListCanvas(
-            node->stagingProperties().getWidth(), node->stagingProperties().getHeight());
-    return renderer;
+// 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;
 }
 
-static void endRecording(DisplayListCanvas* renderer, RenderNode* node) {
-    node->setStagingDisplayList(renderer->finishRecording());
-    delete renderer;
+void Benchmark::registerBenchmark(const BenchmarkInfo& info) {
+    testMap()[info.name] = info;
 }
 
-class TreeContentAnimation {
-public:
-    virtual ~TreeContentAnimation() {}
-    int frameCount = 150;
-    virtual int getFrameCount() { return frameCount; }
-    virtual void setFrameCount(int fc) {
-        if (fc > 0) {
-            frameCount = fc;
-        }
-    }
-    virtual void createContent(int width, int height, DisplayListCanvas* renderer) = 0;
-    virtual void doFrame(int frameNr) = 0;
-
-    template <class T>
-    static void run(int frameCount) {
-        T animation;
-        animation.setFrameCount(frameCount);
-
-        TestContext testContext;
-
-        // create the native surface
-        const int width = gDisplay.w;
-        const int height = gDisplay.h;
-        sp<Surface> surface = testContext.surface();
-
-        RenderNode* rootNode = new RenderNode();
-        rootNode->incStrong(nullptr);
-        rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height);
-        rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-        rootNode->mutateStagingProperties().setClipToBounds(false);
-        rootNode->setPropertyFieldsDirty(RenderNode::GENERIC);
-
-        ContextFactory factory;
-        std::unique_ptr<RenderProxy> proxy(new RenderProxy(false, rootNode, &factory));
-        proxy->loadSystemProperties();
-        proxy->initialize(surface);
-        float lightX = width / 2.0;
-        proxy->setup(width, height, dp(800.0f), 255 * 0.075, 255 * 0.15);
-        proxy->setLightCenter((Vector3){lightX, dp(-200.0f), dp(800.0f)});
-
-        android::uirenderer::Rect DUMMY;
-
-        DisplayListCanvas* renderer = startRecording(rootNode);
-        animation.createContent(width, height, renderer);
-        endRecording(renderer, rootNode);
-
-        // Do a few cold runs then reset the stats so that the caches are all hot
-        for (int i = 0; i < 3; i++) {
-            testContext.waitForVsync();
-            proxy->syncAndDrawFrame();
-        }
-        proxy->resetProfileInfo();
-
-        for (int i = 0; i < animation.getFrameCount(); i++) {
-            testContext.waitForVsync();
-
-            ATRACE_NAME("UI-Draw Frame");
-            nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
-            UiFrameInfoBuilder(proxy->frameInfo())
-                    .setVsync(vsync, vsync);
-            animation.doFrame(i);
-            proxy->syncAndDrawFrame();
-        }
-
-        proxy->dumpProfileInfo(STDOUT_FILENO, 0);
-        rootNode->decStrong(nullptr);
-    }
-};
-
-class ShadowGridAnimation : public TreeContentAnimation {
-public:
-    std::vector< sp<RenderNode> > cards;
-    void createContent(int width, int height, DisplayListCanvas* renderer) override {
-        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
-        renderer->insertReorderBarrier(true);
-
-        for (int x = dp(16); x < (width - dp(116)); x += dp(116)) {
-            for (int y = dp(16); y < (height - dp(116)); y += dp(116)) {
-                sp<RenderNode> card = createCard(x, y, dp(100), dp(100));
-                renderer->drawRenderNode(card.get());
-                cards.push_back(card);
-            }
-        }
-
-        renderer->insertReorderBarrier(false);
-    }
-    void doFrame(int frameNr) override {
-        int curFrame = frameNr % 150;
-        for (size_t ci = 0; ci < cards.size(); ci++) {
-            cards[ci]->mutateStagingProperties().setTranslationX(curFrame);
-            cards[ci]->mutateStagingProperties().setTranslationY(curFrame);
-            cards[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-        }
-    }
-private:
-    sp<RenderNode> createCard(int x, int y, int width, int height) {
-        sp<RenderNode> node = new RenderNode();
-        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
-        node->mutateStagingProperties().setElevation(dp(16));
-        node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1);
-        node->mutateStagingProperties().mutableOutline().setShouldClip(true);
-        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z);
-
-        DisplayListCanvas* renderer = startRecording(node.get());
-        renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode);
-        endRecording(renderer, node.get());
-        return node;
-    }
-};
-
-class ShadowGrid2Animation : public TreeContentAnimation {
-public:
-    std::vector< sp<RenderNode> > cards;
-    void createContent(int width, int height, DisplayListCanvas* renderer) override {
-        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
-        renderer->insertReorderBarrier(true);
-
-        for (int x = dp(8); x < (width - dp(58)); x += dp(58)) {
-            for (int y = dp(8); y < (height - dp(58)); y += dp(58)) {
-                sp<RenderNode> card = createCard(x, y, dp(50), dp(50));
-                renderer->drawRenderNode(card.get());
-                cards.push_back(card);
-            }
-        }
-
-        renderer->insertReorderBarrier(false);
-    }
-    void doFrame(int frameNr) override {
-        int curFrame = frameNr % 150;
-        for (size_t ci = 0; ci < cards.size(); ci++) {
-            cards[ci]->mutateStagingProperties().setTranslationX(curFrame);
-            cards[ci]->mutateStagingProperties().setTranslationY(curFrame);
-            cards[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-        }
-    }
-private:
-    sp<RenderNode> createCard(int x, int y, int width, int height) {
-        sp<RenderNode> node = new RenderNode();
-        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
-        node->mutateStagingProperties().setElevation(dp(16));
-        node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(6), 1);
-        node->mutateStagingProperties().mutableOutline().setShouldClip(true);
-        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z);
-
-        DisplayListCanvas* renderer = startRecording(node.get());
-        renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode);
-        endRecording(renderer, node.get());
-        return node;
-    }
-};
-
-class RectGridAnimation : public TreeContentAnimation {
-public:
-    sp<RenderNode> card;
-    void createContent(int width, int height, DisplayListCanvas* renderer) override {
-        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
-        renderer->insertReorderBarrier(true);
-
-        card = createCard(40, 40, 200, 200);
-        renderer->drawRenderNode(card.get());
-
-        renderer->insertReorderBarrier(false);
-    }
-    void doFrame(int frameNr) override {
-        int curFrame = frameNr % 150;
-        card->mutateStagingProperties().setTranslationX(curFrame);
-        card->mutateStagingProperties().setTranslationY(curFrame);
-        card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-    }
-private:
-    sp<RenderNode> createCard(int x, int y, int width, int height) {
-        sp<RenderNode> node = new RenderNode();
-        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
-        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-
-        DisplayListCanvas* renderer = startRecording(node.get());
-        renderer->drawColor(0xFFFF00FF, SkXfermode::kSrcOver_Mode);
-
-        SkRegion region;
-        for (int xOffset = 0; xOffset < width; xOffset+=2) {
-            for (int yOffset = 0; yOffset < height; yOffset+=2) {
-                region.op(xOffset, yOffset, xOffset + 1, yOffset + 1, SkRegion::kUnion_Op);
-            }
-        }
-
-        SkPaint paint;
-        paint.setColor(0xff00ffff);
-        renderer->drawRegion(region, paint);
-
-        endRecording(renderer, node.get());
-        return node;
-    }
-};
-
-class OvalAnimation : public TreeContentAnimation {
-public:
-    sp<RenderNode> card;
-    void createContent(int width, int height, DisplayListCanvas* renderer) override {
-        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
-        renderer->insertReorderBarrier(true);
-
-        card = createCard(40, 40, 400, 400);
-        renderer->drawRenderNode(card.get());
-
-        renderer->insertReorderBarrier(false);
-    }
-
-    void doFrame(int frameNr) override {
-        int curFrame = frameNr % 150;
-        card->mutateStagingProperties().setTranslationX(curFrame);
-        card->mutateStagingProperties().setTranslationY(curFrame);
-        card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-    }
-private:
-    sp<RenderNode> createCard(int x, int y, int width, int height) {
-        sp<RenderNode> node = new RenderNode();
-        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
-        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-
-        DisplayListCanvas* renderer = startRecording(node.get());
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setColor(0xFF000000);
-        renderer->drawOval(0, 0, width, height, paint);
-
-        endRecording(renderer, node.get());
-        return node;
-    }
-};
-
-class PartialInvalTest : public TreeContentAnimation {
-public:
-    std::vector< sp<RenderNode> > cards;
-    void createContent(int width, int height, DisplayListCanvas* renderer) override {
-        static SkColor COLORS[] = {
-                0xFFF44336,
-                0xFF9C27B0,
-                0xFF2196F3,
-                0xFF4CAF50,
-        };
-
-        renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode);
-
-        for (int x = dp(16); x < (width - dp(116)); x += dp(116)) {
-            for (int y = dp(16); y < (height - dp(116)); y += dp(116)) {
-                sp<RenderNode> card = createCard(x, y, dp(100), dp(100),
-                        COLORS[static_cast<int>((y / dp(116))) % 4]);
-                renderer->drawRenderNode(card.get());
-                cards.push_back(card);
-            }
-        }
-    }
-    void doFrame(int frameNr) override {
-        int curFrame = frameNr % 150;
-        cards[0]->mutateStagingProperties().setTranslationX(curFrame);
-        cards[0]->mutateStagingProperties().setTranslationY(curFrame);
-        cards[0]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-
-        DisplayListCanvas* renderer = startRecording(cards[0].get());
-        renderer->drawColor(interpolateColor(curFrame / 150.0f, 0xFFF44336, 0xFFF8BBD0),
-                SkXfermode::kSrcOver_Mode);
-        endRecording(renderer, cards[0].get());
-    }
-
-    static SkColor interpolateColor(float fraction, SkColor start, SkColor end) {
-        int startA = (start >> 24) & 0xff;
-        int startR = (start >> 16) & 0xff;
-        int startG = (start >> 8) & 0xff;
-        int startB = start & 0xff;
-
-        int endA = (end >> 24) & 0xff;
-        int endR = (end >> 16) & 0xff;
-        int endG = (end >> 8) & 0xff;
-        int endB = end & 0xff;
-
-        return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
-                (int)((startR + (int)(fraction * (endR - startR))) << 16) |
-                (int)((startG + (int)(fraction * (endG - startG))) << 8) |
-                (int)((startB + (int)(fraction * (endB - startB))));
-    }
-private:
-    sp<RenderNode> createCard(int x, int y, int width, int height, SkColor color) {
-        sp<RenderNode> node = new RenderNode();
-        node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height);
-        node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-
-        DisplayListCanvas* renderer = startRecording(node.get());
-        renderer->drawColor(color, SkXfermode::kSrcOver_Mode);
-        endRecording(renderer, node.get());
-        return node;
-    }
-};
-
-struct cstr_cmp {
-    bool operator()(const char *a, const char *b) const {
-        return std::strcmp(a, b) < 0;
-    }
-};
-
-typedef void (*testProc)(int);
-
-std::map<const char*, testProc, cstr_cmp> gTestMap {
-    {"shadowgrid", TreeContentAnimation::run<ShadowGridAnimation>},
-    {"shadowgrid2", TreeContentAnimation::run<ShadowGrid2Animation>},
-    {"rectgrid", TreeContentAnimation::run<RectGridAnimation> },
-    {"oval", TreeContentAnimation::run<OvalAnimation> },
-    {"partialinval", TreeContentAnimation::run<PartialInvalTest> },
-};
-
 static int gFrameCount = 150;
 static int gRepeatCount = 1;
-static std::vector<testProc> gRunTests;
+static std::vector<BenchmarkInfo> gRunTests;
 
 static void printHelp() {
     printf("\
@@ -384,8 +57,31 @@
 
 static void listTests() {
     printf("Tests: \n");
-    for (auto&& test : gTestMap) {
-        printf("%-20s <TODO DESCRIPTION>\n", test.first);
+    for (auto&& test : testMap()) {
+        auto&& info = test.second;
+        const char* col1 = info.name.c_str();
+        int dlen = info.description.length();
+        const char* col2 = info.description.c_str();
+        // World's best line breaking algorithm.
+        do {
+            int toPrint = dlen;
+            if (toPrint > 50) {
+                char* found = (char*) memrchr(col2, ' ', 50);
+                if (found) {
+                    toPrint = found - col2;
+                } else {
+                    toPrint = 50;
+                }
+            }
+            printf("%-20s %.*s\n", col1, toPrint, col2);
+            col1 = "";
+            col2 += toPrint;
+            dlen -= toPrint;
+            while (*col2 == ' ') {
+                col2++; dlen--;
+            }
+        } while (dlen > 0);
+        printf("\n");
     }
 }
 
@@ -470,8 +166,8 @@
     if (optind < argc) {
         do {
             const char* test = argv[optind++];
-            auto pos = gTestMap.find(test);
-            if (pos == gTestMap.end()) {
+            auto pos = testMap().find(test);
+            if (pos == testMap().end()) {
                 fprintf(stderr, "Unknown test '%s'\n", test);
                 exit(EXIT_FAILURE);
             } else {
@@ -479,16 +175,18 @@
             }
         } while (optind < argc);
     } else {
-        gRunTests.push_back(gTestMap["shadowgrid"]);
+        gRunTests.push_back(testMap()["shadowgrid"]);
     }
 }
 
 int main(int argc, char* argv[]) {
     parseOptions(argc, argv);
 
+    BenchmarkOptions opts;
+    opts.count = gFrameCount;
     for (int i = 0; i < gRepeatCount; i++) {
         for (auto&& test : gRunTests) {
-            test(gFrameCount);
+            test.functor(opts);
         }
     }
     printf("Success!\n");
