Add a performance tests target.

Include a preliminary implementation of a simple benchmark app.

BUG=angle:705

Change-Id: I627450f6fdf01ed2054a50bd2327b7b9128c86f5
Reviewed-on: https://chromium-review.googlesource.com/214230
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/tests/perf_tests/SimpleBenchmark.cpp b/tests/perf_tests/SimpleBenchmark.cpp
new file mode 100644
index 0000000..b47daf0
--- /dev/null
+++ b/tests/perf_tests/SimpleBenchmark.cpp
@@ -0,0 +1,131 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "SimpleBenchmark.h"
+#include <iostream>
+
+SimpleBenchmark::SimpleBenchmark(const std::string &name, size_t width, size_t height, EGLint glesMajorVersion, EGLint requestedRenderer)
+    : mNumFrames(0),
+      mName(name),
+      mRunning(false)
+{
+    mOSWindow.reset(CreateOSWindow());
+    mEGLWindow.reset(new EGLWindow(width, height, glesMajorVersion, requestedRenderer));
+    mTimer.reset(CreateTimer());
+}
+
+bool SimpleBenchmark::initialize()
+{
+    std::cout << "========= " << mName << " =========" << std::endl;
+    return initializeBenchmark();
+}
+
+void SimpleBenchmark::destroy()
+{
+    double totalTime = mTimer->getElapsedTime();
+    std::cout << " - total time: " << totalTime << " sec" << std::endl;
+    std::cout << " - frames: " << mNumFrames << std::endl;
+    std::cout << " - average frame time: " << 1000.0 * totalTime / mNumFrames << " msec" << std::endl;
+    std::cout << "=========" << std::endl << std::endl;
+
+    destroyBenchmark();
+}
+
+void SimpleBenchmark::step(float dt, double totalTime)
+{
+    stepBenchmark(dt, totalTime);
+}
+
+void SimpleBenchmark::draw()
+{
+    if (mTimer->getElapsedTime() > runTimeSeconds()) {
+        mRunning = false;
+        return;
+    }
+
+    ++mNumFrames;
+
+    beginDrawBenchmark();
+
+    for (int i = 0; i < drawIterations(); ++i)
+    {
+        drawBenchmark();
+    }
+
+    endDrawBenchmark();
+}
+
+int SimpleBenchmark::run()
+{
+    if (!mOSWindow->initialize(mName, mEGLWindow->getWidth(), mEGLWindow->getHeight()))
+    {
+        return -1;
+    }
+
+    if (!mEGLWindow->initializeGL(mOSWindow.get()))
+    {
+        return -1;
+    }
+
+    mRunning = true;
+    int result = 0;
+
+    if (!initialize())
+    {
+        mRunning = false;
+        result = -1;
+    }
+
+    mTimer->start();
+    double prevTime = 0.0;
+
+    while (mRunning)
+    {
+        double elapsedTime = mTimer->getElapsedTime();
+        double deltaTime = elapsedTime - prevTime;
+
+        step(static_cast<float>(deltaTime), elapsedTime);
+
+        // Clear events that the application did not process from this frame
+        Event event;
+        while (popEvent(&event))
+        {
+            // If the application did not catch a close event, close now
+            if (event.Type == Event::EVENT_CLOSED)
+            {
+                mRunning = false;
+            }
+        }
+
+        if (!mRunning)
+        {
+            break;
+        }
+
+        draw();
+        mEGLWindow->swap();
+
+        mOSWindow->messageLoop();
+
+        prevTime = elapsedTime;
+    }
+
+    destroy();
+    mEGLWindow->destroyGL();
+    mOSWindow->destroy();
+
+    return result;
+}
+
+bool SimpleBenchmark::popEvent(Event *event)
+{
+    return mOSWindow->popEvent(event);
+}
+
+OSWindow *SimpleBenchmark::getWindow()
+{
+    return mOSWindow.get();
+}
\ No newline at end of file
diff --git a/tests/perf_tests/SimpleBenchmark.h b/tests/perf_tests/SimpleBenchmark.h
new file mode 100644
index 0000000..76ffd88
--- /dev/null
+++ b/tests/perf_tests/SimpleBenchmark.h
@@ -0,0 +1,89 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef SAMPLE_UTIL_SIMPLE_BENCHMARK_H
+#define SAMPLE_UTIL_SIMPLE_BENCHMARK_H
+
+#include <memory>
+#include <vector>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <string>
+
+#include "shared_utils.h"
+
+#include "OSWindow.h"
+#include "EGLWindow.h"
+#include "Timer.h"
+
+class Event;
+
+class SimpleBenchmark
+{
+  public:
+    SimpleBenchmark(const std::string &name, size_t width, size_t height,
+                    EGLint glesMajorVersion = 2,
+                    EGLint requestedRenderer = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+
+    virtual ~SimpleBenchmark() { };
+
+    virtual int drawIterations() const { return 10; }
+    virtual double runTimeSeconds() const { return 10.0; }
+
+    virtual bool initializeBenchmark() { return true; }
+    virtual void destroyBenchmark() { }
+
+    virtual void stepBenchmark(float dt, double totalTime) { }
+
+    virtual void beginDrawBenchmark() { }
+    virtual void drawBenchmark() = 0;
+    virtual void endDrawBenchmark() { }
+
+    int run();
+    bool popEvent(Event *event);
+
+    OSWindow *getWindow();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(SimpleBenchmark);
+
+    bool initialize();
+    void destroy();
+
+    void step(float dt, double totalTime);
+    void draw();
+
+    int mNumFrames;
+    std::string mName;
+    bool mRunning;
+
+    std::unique_ptr<EGLWindow> mEGLWindow;
+    std::unique_ptr<OSWindow> mOSWindow;
+    std::unique_ptr<Timer> mTimer;
+};
+
+// Base class
+struct BenchmarkParams
+{
+    virtual std::string name() const = 0;
+};
+
+template <typename BenchmarkT, typename ParamsT>
+inline int RunBenchmarks(const std::vector<ParamsT> &benchmarks)
+{
+    int result;
+
+    for (size_t benchIndex = 0; benchIndex < benchmarks.size(); benchIndex++)
+    {
+        BenchmarkT benchmark(benchmarks[benchIndex]);
+        result = benchmark.run();
+        if (result != 0) { return result; }
+    }
+
+    return 0;
+}
+
+#endif // SAMPLE_UTIL_SIMPLE_BENCHMARK_H
diff --git a/tests/perf_tests/SimpleBenchmarks.cpp b/tests/perf_tests/SimpleBenchmarks.cpp
new file mode 100644
index 0000000..d538fd7
--- /dev/null
+++ b/tests/perf_tests/SimpleBenchmarks.cpp
@@ -0,0 +1,12 @@
+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "SimpleBenchmark.h"
+
+int main(int argc, char **argv)
+{
+    // TODO
+}
diff --git a/tests/tests.gyp b/tests/tests.gyp
index ee6d696..ef0f7a6 100644
--- a/tests/tests.gyp
+++ b/tests/tests.gyp
@@ -191,6 +191,29 @@
                         '<!@(python <(angle_path)/enumerate_files.py standalone_tests -types *.cpp *.h)'
                     ],
                 },
+                {
+                    'target_name': 'angle_perf_tests',
+                    'type': 'executable',
+                    'includes': [ '../build/common_defines.gypi', ],
+                    'dependencies':
+                    [
+                        '../src/angle.gyp:libGLESv2',
+                        '../src/angle.gyp:libEGL',
+                        'gtest',
+                        '../util/util.gyp:angle_util',
+                    ],
+                    'include_dirs':
+                    [
+                        '../include',
+                        'third_party/googletest/include',
+                    ],
+                    'sources':
+                    [
+                        'perf_tests/SimpleBenchmark.cpp',
+                        'perf_tests/SimpleBenchmark.h',
+                        'perf_tests/SimpleBenchmarks.cpp',
+                    ],
+                },
             ],
             'conditions':
             [