• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // ANGLEPerfTests:
7 //   Base class for google test performance tests
8 //
9 
10 #ifndef PERF_TESTS_ANGLE_PERF_TEST_H_
11 #define PERF_TESTS_ANGLE_PERF_TEST_H_
12 
13 #include <gtest/gtest.h>
14 
15 #include <string>
16 #include <unordered_map>
17 #include <vector>
18 
19 #include "platform/PlatformMethods.h"
20 #include "test_utils/angle_test_configs.h"
21 #include "test_utils/angle_test_instantiate.h"
22 #include "test_utils/angle_test_platform.h"
23 #include "third_party/perf/perf_result_reporter.h"
24 #include "util/EGLWindow.h"
25 #include "util/OSWindow.h"
26 #include "util/Timer.h"
27 #include "util/util_gl.h"
28 
29 class Event;
30 
31 #if !defined(ASSERT_GL_NO_ERROR)
32 #    define ASSERT_GL_NO_ERROR() ASSERT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError())
33 #endif  // !defined(ASSERT_GL_NO_ERROR)
34 
35 #if !defined(ASSERT_GLENUM_EQ)
36 #    define ASSERT_GLENUM_EQ(expected, actual) \
37         ASSERT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
38 #endif  // !defined(ASSERT_GLENUM_EQ)
39 
40 // These are trace events according to Google's "Trace Event Format".
41 // See https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
42 // Only a subset of the properties are implemented.
43 struct TraceEvent final
44 {
TraceEventfinal45     TraceEvent() {}
46     TraceEvent(char phaseIn, const char *categoryNameIn, const char *nameIn, double timestampIn);
47 
48     static constexpr uint32_t kMaxNameLen = 64;
49 
50     char phase               = 0;
51     const char *categoryName = nullptr;
52     char name[kMaxNameLen]   = {};
53     double timestamp         = 0;
54     uint32_t tid             = 0;
55 };
56 
57 class ANGLEPerfTest : public testing::Test, angle::NonCopyable
58 {
59   public:
60     ANGLEPerfTest(const std::string &name,
61                   const std::string &backend,
62                   const std::string &story,
63                   unsigned int iterationsPerStep);
64     ~ANGLEPerfTest() override;
65 
66     virtual void step() = 0;
67 
68     // Called right after the timer starts to let the test initialize other metrics if necessary
startTest()69     virtual void startTest() {}
70     // Called right before timer is stopped to let the test wait for asynchronous operations.
finishTest()71     virtual void finishTest() {}
flush()72     virtual void flush() {}
73 
74   protected:
75     void run();
76     void SetUp() override;
77     void TearDown() override;
78 
79     // Normalize a time value according to the number of test loop iterations (mFrameCount)
80     double normalizedTime(size_t value) const;
81 
82     // Call if the test step was aborted and the test should stop running.
abortTest()83     void abortTest() { mRunning = false; }
84 
getNumStepsPerformed()85     unsigned int getNumStepsPerformed() const { return mNumStepsPerformed; }
86     void doRunLoop(double maxRunTime);
87 
88     // Overriden in trace perf tests.
saveScreenshot(const std::string & screenshotName)89     virtual void saveScreenshot(const std::string &screenshotName) {}
90 
91     std::string mName;
92     std::string mBackend;
93     std::string mStory;
94     Timer mTimer;
95     uint64_t mGPUTimeNs;
96     bool mSkipTest;
97     std::unique_ptr<perf_test::PerfResultReporter> mReporter;
98 
99   private:
100     double printResults();
101 
102     unsigned int mStepsToRun;
103     unsigned int mNumStepsPerformed;
104     unsigned int mIterationsPerStep;
105     bool mRunning;
106 };
107 
108 struct RenderTestParams : public angle::PlatformParameters
109 {
~RenderTestParamsRenderTestParams110     virtual ~RenderTestParams() {}
111 
112     virtual std::string backend() const;
113     virtual std::string story() const;
114     std::string backendAndStory() const;
115 
116     EGLint windowWidth             = 64;
117     EGLint windowHeight            = 64;
118     unsigned int iterationsPerStep = 0;
119     bool trackGpuTime              = false;
120 };
121 
122 class ANGLERenderTest : public ANGLEPerfTest
123 {
124   public:
125     ANGLERenderTest(const std::string &name, const RenderTestParams &testParams);
126     ~ANGLERenderTest() override;
127 
128     void addExtensionPrerequisite(const char *extensionName);
129 
initializeBenchmark()130     virtual void initializeBenchmark() {}
destroyBenchmark()131     virtual void destroyBenchmark() {}
132 
133     virtual void drawBenchmark() = 0;
134 
135     bool popEvent(Event *event);
136 
137     OSWindow *getWindow();
138     GLWindowBase *getGLWindow();
139 
140     std::vector<TraceEvent> &getTraceEventBuffer();
141 
overrideWorkaroundsD3D(angle::FeaturesD3D * featuresD3D)142     virtual void overrideWorkaroundsD3D(angle::FeaturesD3D *featuresD3D) {}
143 
144   protected:
145     const RenderTestParams &mTestParams;
146 
147     void setWebGLCompatibilityEnabled(bool webglCompatibility);
148     void setRobustResourceInit(bool enabled);
149 
150     void startGpuTimer();
151     void stopGpuTimer();
152 
153     void beginInternalTraceEvent(const char *name);
154     void endInternalTraceEvent(const char *name);
155     void beginGLTraceEvent(const char *name, double hostTimeSec);
156     void endGLTraceEvent(const char *name, double hostTimeSec);
157 
disableTestHarnessSwap()158     void disableTestHarnessSwap() { mSwapEnabled = false; }
159 
160     bool mIsTimestampQueryAvailable;
161 
162   private:
163     void SetUp() override;
164     void TearDown() override;
165 
166     void step() override;
167     void startTest() override;
168     void finishTest() override;
169 
170     bool areExtensionPrerequisitesFulfilled() const;
171 
172     GLWindowBase *mGLWindow;
173     OSWindow *mOSWindow;
174     std::vector<const char *> mExtensionPrerequisites;
175     angle::PlatformMethods mPlatformMethods;
176     ConfigParameters mConfigParams;
177     bool mSwapEnabled;
178 
179     GLuint mTimestampQuery;
180 
181     // Trace event record that can be output.
182     std::vector<TraceEvent> mTraceEventBuffer;
183 
184     // Handle to the entry point binding library.
185     std::unique_ptr<angle::Library> mEntryPointsLib;
186 };
187 
188 // Mixins.
189 namespace params
190 {
191 template <typename ParamsT>
Offscreen(const ParamsT & input)192 ParamsT Offscreen(const ParamsT &input)
193 {
194     ParamsT output   = input;
195     output.offscreen = true;
196     return output;
197 }
198 
199 template <typename ParamsT>
NullDevice(const ParamsT & input)200 ParamsT NullDevice(const ParamsT &input)
201 {
202     ParamsT output                  = input;
203     output.eglParameters.deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE;
204     output.trackGpuTime             = false;
205     return output;
206 }
207 
208 template <typename ParamsT>
Passthrough(const ParamsT & input)209 ParamsT Passthrough(const ParamsT &input)
210 {
211     return input;
212 }
213 }  // namespace params
214 
215 namespace angle
216 {
217 // Returns the time of the host since the application started in seconds.
218 double GetHostTimeSeconds();
219 }  // namespace angle
220 #endif  // PERF_TESTS_ANGLE_PERF_TEST_H_
221