Replace sleep() hack with vsync listening

Change-Id: I4eb744d9a5abe40cf4f8bbaafa03e59b7360608a
diff --git a/libs/hwui/tests/TestContext.cpp b/libs/hwui/tests/TestContext.cpp
index 35e402d..542bbae 100644
--- a/libs/hwui/tests/TestContext.cpp
+++ b/libs/hwui/tests/TestContext.cpp
@@ -16,30 +16,59 @@
 
 #include "TestContext.h"
 
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
+namespace android {
+namespace uirenderer {
+namespace test {
 
-using namespace android;
+static const int IDENT_DISPLAYEVENT = 1;
 
-DisplayInfo gDisplay;
-sp<SurfaceComposerClient> gSession;
-
-void createTestEnvironment() {
-    gSession = new SurfaceComposerClient();
+static DisplayInfo getBuiltInDisplay() {
+    DisplayInfo display;
     sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
-                ISurfaceComposer::eDisplayIdMain));
-    status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &gDisplay);
+            ISurfaceComposer::eDisplayIdMain));
+    status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &display);
     LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n");
+    return display;
 }
 
-sp<SurfaceControl> createWindow(int width, int height) {
-    sp<SurfaceControl> control = gSession->createSurface(String8("HwuiTest"),
-            width, height, PIXEL_FORMAT_RGBX_8888);
+android::DisplayInfo gDisplay = getBuiltInDisplay();
 
-    SurfaceComposerClient::openGlobalTransaction();
-    control->setLayer(0x7FFFFFF);
-    control->show();
-    SurfaceComposerClient::closeGlobalTransaction();
-
-    return control;
+TestContext::TestContext() {
+    mLooper = new Looper(true);
+    mSurfaceComposerClient = new SurfaceComposerClient();
+    mLooper->addFd(mDisplayEventReceiver.getFd(), IDENT_DISPLAYEVENT,
+            Looper::EVENT_INPUT, nullptr, nullptr);
 }
+
+TestContext::~TestContext() {}
+
+sp<Surface> TestContext::surface() {
+    if (!mSurfaceControl.get()) {
+        mSurfaceControl = mSurfaceComposerClient->createSurface(String8("HwuiTest"),
+                gDisplay.w, gDisplay.h, PIXEL_FORMAT_RGBX_8888);
+
+        SurfaceComposerClient::openGlobalTransaction();
+        mSurfaceControl->setLayer(0x7FFFFFF);
+        mSurfaceControl->show();
+        SurfaceComposerClient::closeGlobalTransaction();
+    }
+
+    return mSurfaceControl->getSurface();
+}
+
+void TestContext::waitForVsync() {
+    // Request vsync
+    mDisplayEventReceiver.requestNextVsync();
+
+    // Wait
+    mLooper->pollOnce(-1);
+
+    // Drain it
+    DisplayEventReceiver::Event buf[100];
+    while (mDisplayEventReceiver.getEvents(buf, 100) > 0) { }
+}
+
+} // namespace test
+} // namespace uirenderer
+} // namespace android
+
diff --git a/libs/hwui/tests/TestContext.h b/libs/hwui/tests/TestContext.h
index 8a5d530..7b30fc1 100644
--- a/libs/hwui/tests/TestContext.h
+++ b/libs/hwui/tests/TestContext.h
@@ -17,17 +17,39 @@
 #ifndef TESTCONTEXT_H
 #define TESTCONTEXT_H
 
-#include <ui/DisplayInfo.h>
+#include <gui/DisplayEventReceiver.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
 #include <gui/SurfaceControl.h>
+#include <gui/Surface.h>
+#include <ui/DisplayInfo.h>
+#include <utils/Looper.h>
 
-extern android::DisplayInfo gDisplay;
-#define dp(x) ((x) * gDisplay.density)
+namespace android {
+namespace uirenderer {
+namespace test {
 
-// Initializes all the static globals that are shared across all contexts
-// such as display info
-void createTestEnvironment();
+extern DisplayInfo gDisplay;
+#define dp(x) ((x) * android::uirenderer::test::gDisplay.density)
 
-// Defaults to fullscreen
-android::sp<android::SurfaceControl> createWindow(int width = -1, int height = -1);
+class TestContext {
+public:
+    TestContext();
+    ~TestContext();
+
+    sp<Surface> surface();
+
+    void waitForVsync();
+
+private:
+    sp<SurfaceComposerClient> mSurfaceComposerClient;
+    sp<SurfaceControl> mSurfaceControl;
+    DisplayEventReceiver mDisplayEventReceiver;
+    sp<Looper> mLooper;
+};
+
+} // namespace test
+} // namespace uirenderer
+} // namespace android
 
 #endif
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index 152e7b2..a12dac7 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -24,12 +24,14 @@
 #include <DisplayListRenderer.h>
 #include <RenderNode.h>
 #include <renderthread/RenderProxy.h>
+#include <renderthread/RenderTask.h>
 
 #include "TestContext.h"
 
 using namespace android;
 using namespace android::uirenderer;
 using namespace android::uirenderer::renderthread;
+using namespace android::uirenderer::test;
 
 class ContextFactory : public IContextFactory {
 public:
@@ -67,13 +69,12 @@
 }
 
 int main(int argc, char* argv[]) {
-    createTestEnvironment();
+    TestContext testContext;
 
     // create the native surface
     const int width = gDisplay.w;
     const int height = gDisplay.h;
-    sp<SurfaceControl> control = createWindow(width, height);
-    sp<Surface> surface = control->getSurface();
+    sp<Surface> surface = testContext.surface();
 
     RenderNode* rootNode = new RenderNode();
     rootNode->incStrong(nullptr);
@@ -110,6 +111,8 @@
     endRecording(renderer, rootNode);
 
     for (int i = 0; i < 150; i++) {
+        testContext.waitForVsync();
+
         ATRACE_NAME("UI-Draw Frame");
         for (size_t ci = 0; ci < cards.size(); ci++) {
             cards[ci]->mutateStagingProperties().setTranslationX(i);
@@ -118,7 +121,6 @@
         }
         nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC);
         proxy->syncAndDrawFrame(frameTimeNs, 0, gDisplay.density);
-        usleep(12000);
     }
 
     sleep(5);