Dump profile info after running test

Bug: 20824843

Not really a proper "benchmark mode" but it turns out
we already have reasonably good profile data, so tweak
the test app to spit it out after a run.

Change-Id: Iaee9c0d61b5508daf282fe5f95d0b37ee419a8f1
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 7c04f40..a7bfb84 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -383,8 +383,10 @@
     mRenderThread.queueAtFront(task);
 }
 
-CREATE_BRIDGE3(dumpProfileInfo, CanvasContext* context, int fd, int dumpFlags) {
+CREATE_BRIDGE4(dumpProfileInfo, CanvasContext* context, RenderThread* thread,
+        int fd, int dumpFlags) {
     args->context->profiler().dumpData(args->fd);
+    args->thread->jankTracker().dump(args->fd);
     if (args->dumpFlags & DumpFlags::kFrameStats) {
         args->context->dumpFrames(args->fd);
     }
@@ -397,11 +399,23 @@
 void RenderProxy::dumpProfileInfo(int fd, int dumpFlags) {
     SETUP_TASK(dumpProfileInfo);
     args->context = mContext;
+    args->thread = &mRenderThread;
     args->fd = fd;
     args->dumpFlags = dumpFlags;
     postAndWait(task);
 }
 
+CREATE_BRIDGE1(resetProfileInfo, CanvasContext* context) {
+    args->context->resetFrameStats();
+    return nullptr;
+}
+
+void RenderProxy::resetProfileInfo() {
+    SETUP_TASK(resetProfileInfo);
+    args->context = mContext;
+    postAndWait(task);
+}
+
 CREATE_BRIDGE2(dumpGraphicsMemory, int fd, RenderThread* thread) {
     args->thread->jankTracker().dump(args->fd);
 
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index cc475fa..a1dbc7d 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -96,6 +96,8 @@
     ANDROID_API void notifyFramePending();
 
     ANDROID_API void dumpProfileInfo(int fd, int dumpFlags);
+    // Not exported, only used for testing
+    void resetProfileInfo();
     ANDROID_API static void dumpGraphicsMemory(int fd);
 
     ANDROID_API void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size);
diff --git a/libs/hwui/tests/TestContext.cpp b/libs/hwui/tests/TestContext.cpp
index 542bbae..3687a50 100644
--- a/libs/hwui/tests/TestContext.cpp
+++ b/libs/hwui/tests/TestContext.cpp
@@ -57,6 +57,10 @@
 }
 
 void TestContext::waitForVsync() {
+#if HWUI_NULL_GPU
+    return;
+#endif
+
     // Request vsync
     mDisplayEventReceiver.requestNextVsync();
 
@@ -71,4 +75,3 @@
 } // namespace test
 } // namespace uirenderer
 } // namespace android
-
diff --git a/libs/hwui/tests/how_to_run.txt b/libs/hwui/tests/how_to_run.txt
new file mode 100644
index 0000000..686cd78
--- /dev/null
+++ b/libs/hwui/tests/how_to_run.txt
@@ -0,0 +1,17 @@
+mmm -j8 frameworks/base/libs/hwui/tests/ &&
+    adb push $OUT/data/local/tmp/hwuitest /data/local/tmp/hwuitest &&
+    adb shell /data/local/tmp/hwuitest
+
+
+Command arguments:
+hwuitest [testname]
+
+Default test is 'shadowgrid'
+
+List of tests:
+
+shadowgrid: creates a grid of rounded rects that cast shadows, high CPU & GPU load
+
+rectgrid: creates a grid of 1x1 rects
+
+oval: draws 1 oval
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index 62782af..aca7c52 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include <stdio.h>
-
 #include <cutils/log.h>
 #include <gui/Surface.h>
 #include <ui/PixelFormat.h>
@@ -28,6 +26,9 @@
 
 #include "TestContext.h"
 
+#include <stdio.h>
+#include <unistd.h>
+
 using namespace android;
 using namespace android::uirenderer;
 using namespace android::uirenderer::renderthread;
@@ -93,16 +94,27 @@
         animation.createContent(width, height, renderer);
         endRecording(renderer, rootNode);
 
-        for (int i = 0; i < animation.getFrameCount(); i++) {
-#if !HWUI_NULL_GPU
+        // 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();
-#endif
+            proxy->syncAndDrawFrame();
+        }
+        proxy->resetProfileInfo();
 
+        for (int i = 0; i < animation.getFrameCount(); i++) {
+            testContext.waitForVsync();
+
+            // workaround b/20853441
+            proxy->fence();
             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);
     }
 };