xref: /aosp_15_r20/external/angle/src/tests/perf_tests/ANGLEPerfTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // ANGLEPerfTests:
7*8975f5c5SAndroid Build Coastguard Worker //   Base class for google test performance tests
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "ANGLEPerfTest.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_ANDROID)
13*8975f5c5SAndroid Build Coastguard Worker #    include <android/log.h>
14*8975f5c5SAndroid Build Coastguard Worker #    include <dlfcn.h>
15*8975f5c5SAndroid Build Coastguard Worker #endif
16*8975f5c5SAndroid Build Coastguard Worker #include "ANGLEPerfTestArgs.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "common/base/anglebase/trace_event/trace_event.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "common/gl_enum_utils.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "common/platform.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "common/string_utils.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/runner/TestSuite.h"
26*8975f5c5SAndroid Build Coastguard Worker #include "third_party/perf/perf_test.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
28*8975f5c5SAndroid Build Coastguard Worker #include "util/test_utils.h"
29*8975f5c5SAndroid Build Coastguard Worker 
30*8975f5c5SAndroid Build Coastguard Worker #include <cassert>
31*8975f5c5SAndroid Build Coastguard Worker #include <cmath>
32*8975f5c5SAndroid Build Coastguard Worker #include <fstream>
33*8975f5c5SAndroid Build Coastguard Worker #include <iostream>
34*8975f5c5SAndroid Build Coastguard Worker #include <numeric>
35*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
36*8975f5c5SAndroid Build Coastguard Worker #include <string>
37*8975f5c5SAndroid Build Coastguard Worker 
38*8975f5c5SAndroid Build Coastguard Worker #include <rapidjson/document.h>
39*8975f5c5SAndroid Build Coastguard Worker #include <rapidjson/filewritestream.h>
40*8975f5c5SAndroid Build Coastguard Worker #include <rapidjson/istreamwrapper.h>
41*8975f5c5SAndroid Build Coastguard Worker #include <rapidjson/prettywriter.h>
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
44*8975f5c5SAndroid Build Coastguard Worker #    include "util/windows/WGLWindow.h"
45*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_USE_UTIL_LOADER) &&defined(ANGLE_PLATFORM_WINDOWS)
46*8975f5c5SAndroid Build Coastguard Worker 
47*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
48*8975f5c5SAndroid Build Coastguard Worker namespace js = rapidjson;
49*8975f5c5SAndroid Build Coastguard Worker 
50*8975f5c5SAndroid Build Coastguard Worker namespace
51*8975f5c5SAndroid Build Coastguard Worker {
52*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kInitialTraceEventBufferSize            = 50000;
53*8975f5c5SAndroid Build Coastguard Worker constexpr double kMilliSecondsPerSecond                  = 1e3;
54*8975f5c5SAndroid Build Coastguard Worker constexpr double kMicroSecondsPerSecond                  = 1e6;
55*8975f5c5SAndroid Build Coastguard Worker constexpr double kNanoSecondsPerSecond                   = 1e9;
56*8975f5c5SAndroid Build Coastguard Worker constexpr size_t kNumberOfStepsPerformedToComputeGPUTime = 16;
57*8975f5c5SAndroid Build Coastguard Worker constexpr char kPeakMemoryMetric[]                       = ".memory_max";
58*8975f5c5SAndroid Build Coastguard Worker constexpr char kMedianMemoryMetric[]                     = ".memory_median";
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker struct TraceCategory
61*8975f5c5SAndroid Build Coastguard Worker {
62*8975f5c5SAndroid Build Coastguard Worker     unsigned char enabled;
63*8975f5c5SAndroid Build Coastguard Worker     const char *name;
64*8975f5c5SAndroid Build Coastguard Worker };
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker constexpr TraceCategory gTraceCategories[2] = {
67*8975f5c5SAndroid Build Coastguard Worker     {1, "gpu.angle"},
68*8975f5c5SAndroid Build Coastguard Worker     {1, "gpu.angle.gpu"},
69*8975f5c5SAndroid Build Coastguard Worker };
70*8975f5c5SAndroid Build Coastguard Worker 
EmptyPlatformMethod(PlatformMethods *,const char *)71*8975f5c5SAndroid Build Coastguard Worker void EmptyPlatformMethod(PlatformMethods *, const char *) {}
72*8975f5c5SAndroid Build Coastguard Worker 
CustomLogError(PlatformMethods * platform,const char * errorMessage)73*8975f5c5SAndroid Build Coastguard Worker void CustomLogError(PlatformMethods *platform, const char *errorMessage)
74*8975f5c5SAndroid Build Coastguard Worker {
75*8975f5c5SAndroid Build Coastguard Worker     auto *angleRenderTest = static_cast<ANGLERenderTest *>(platform->context);
76*8975f5c5SAndroid Build Coastguard Worker     angleRenderTest->onErrorMessage(errorMessage);
77*8975f5c5SAndroid Build Coastguard Worker }
78*8975f5c5SAndroid Build Coastguard Worker 
AddPerfTraceEvent(PlatformMethods * platform,char phase,const unsigned char * categoryEnabledFlag,const char * name,unsigned long long id,double timestamp,int numArgs,const char ** argNames,const unsigned char * argTypes,const unsigned long long * argValues,unsigned char flags)79*8975f5c5SAndroid Build Coastguard Worker TraceEventHandle AddPerfTraceEvent(PlatformMethods *platform,
80*8975f5c5SAndroid Build Coastguard Worker                                    char phase,
81*8975f5c5SAndroid Build Coastguard Worker                                    const unsigned char *categoryEnabledFlag,
82*8975f5c5SAndroid Build Coastguard Worker                                    const char *name,
83*8975f5c5SAndroid Build Coastguard Worker                                    unsigned long long id,
84*8975f5c5SAndroid Build Coastguard Worker                                    double timestamp,
85*8975f5c5SAndroid Build Coastguard Worker                                    int numArgs,
86*8975f5c5SAndroid Build Coastguard Worker                                    const char **argNames,
87*8975f5c5SAndroid Build Coastguard Worker                                    const unsigned char *argTypes,
88*8975f5c5SAndroid Build Coastguard Worker                                    const unsigned long long *argValues,
89*8975f5c5SAndroid Build Coastguard Worker                                    unsigned char flags)
90*8975f5c5SAndroid Build Coastguard Worker {
91*8975f5c5SAndroid Build Coastguard Worker     if (!gEnableTrace)
92*8975f5c5SAndroid Build Coastguard Worker         return 0;
93*8975f5c5SAndroid Build Coastguard Worker 
94*8975f5c5SAndroid Build Coastguard Worker     // Discover the category name based on categoryEnabledFlag.  This flag comes from the first
95*8975f5c5SAndroid Build Coastguard Worker     // parameter of TraceCategory, and corresponds to one of the entries in gTraceCategories.
96*8975f5c5SAndroid Build Coastguard Worker     static_assert(offsetof(TraceCategory, enabled) == 0,
97*8975f5c5SAndroid Build Coastguard Worker                   "|enabled| must be the first field of the TraceCategory class.");
98*8975f5c5SAndroid Build Coastguard Worker     const TraceCategory *category = reinterpret_cast<const TraceCategory *>(categoryEnabledFlag);
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker     ANGLERenderTest *renderTest = static_cast<ANGLERenderTest *>(platform->context);
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(renderTest->getTraceEventMutex());
103*8975f5c5SAndroid Build Coastguard Worker 
104*8975f5c5SAndroid Build Coastguard Worker     uint32_t tid = renderTest->getCurrentThreadSerial();
105*8975f5c5SAndroid Build Coastguard Worker 
106*8975f5c5SAndroid Build Coastguard Worker     std::vector<TraceEvent> &buffer = renderTest->getTraceEventBuffer();
107*8975f5c5SAndroid Build Coastguard Worker     buffer.emplace_back(phase, category->name, name, timestamp, tid);
108*8975f5c5SAndroid Build Coastguard Worker     return buffer.size();
109*8975f5c5SAndroid Build Coastguard Worker }
110*8975f5c5SAndroid Build Coastguard Worker 
GetPerfTraceCategoryEnabled(PlatformMethods * platform,const char * categoryName)111*8975f5c5SAndroid Build Coastguard Worker const unsigned char *GetPerfTraceCategoryEnabled(PlatformMethods *platform,
112*8975f5c5SAndroid Build Coastguard Worker                                                  const char *categoryName)
113*8975f5c5SAndroid Build Coastguard Worker {
114*8975f5c5SAndroid Build Coastguard Worker     if (gEnableTrace)
115*8975f5c5SAndroid Build Coastguard Worker     {
116*8975f5c5SAndroid Build Coastguard Worker         for (const TraceCategory &category : gTraceCategories)
117*8975f5c5SAndroid Build Coastguard Worker         {
118*8975f5c5SAndroid Build Coastguard Worker             if (strcmp(category.name, categoryName) == 0)
119*8975f5c5SAndroid Build Coastguard Worker             {
120*8975f5c5SAndroid Build Coastguard Worker                 return &category.enabled;
121*8975f5c5SAndroid Build Coastguard Worker             }
122*8975f5c5SAndroid Build Coastguard Worker         }
123*8975f5c5SAndroid Build Coastguard Worker     }
124*8975f5c5SAndroid Build Coastguard Worker 
125*8975f5c5SAndroid Build Coastguard Worker     constexpr static unsigned char kZero = 0;
126*8975f5c5SAndroid Build Coastguard Worker     return &kZero;
127*8975f5c5SAndroid Build Coastguard Worker }
128*8975f5c5SAndroid Build Coastguard Worker 
UpdateTraceEventDuration(PlatformMethods * platform,const unsigned char * categoryEnabledFlag,const char * name,TraceEventHandle eventHandle)129*8975f5c5SAndroid Build Coastguard Worker void UpdateTraceEventDuration(PlatformMethods *platform,
130*8975f5c5SAndroid Build Coastguard Worker                               const unsigned char *categoryEnabledFlag,
131*8975f5c5SAndroid Build Coastguard Worker                               const char *name,
132*8975f5c5SAndroid Build Coastguard Worker                               TraceEventHandle eventHandle)
133*8975f5c5SAndroid Build Coastguard Worker {
134*8975f5c5SAndroid Build Coastguard Worker     // Not implemented.
135*8975f5c5SAndroid Build Coastguard Worker }
136*8975f5c5SAndroid Build Coastguard Worker 
MonotonicallyIncreasingTime(PlatformMethods * platform)137*8975f5c5SAndroid Build Coastguard Worker double MonotonicallyIncreasingTime(PlatformMethods *platform)
138*8975f5c5SAndroid Build Coastguard Worker {
139*8975f5c5SAndroid Build Coastguard Worker     return GetHostTimeSeconds();
140*8975f5c5SAndroid Build Coastguard Worker }
141*8975f5c5SAndroid Build Coastguard Worker 
WriteJsonFile(const std::string & outputFile,js::Document * doc)142*8975f5c5SAndroid Build Coastguard Worker bool WriteJsonFile(const std::string &outputFile, js::Document *doc)
143*8975f5c5SAndroid Build Coastguard Worker {
144*8975f5c5SAndroid Build Coastguard Worker     FILE *fp = fopen(outputFile.c_str(), "w");
145*8975f5c5SAndroid Build Coastguard Worker     if (!fp)
146*8975f5c5SAndroid Build Coastguard Worker     {
147*8975f5c5SAndroid Build Coastguard Worker         return false;
148*8975f5c5SAndroid Build Coastguard Worker     }
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t kBufferSize = 0xFFFF;
151*8975f5c5SAndroid Build Coastguard Worker     std::vector<char> writeBuffer(kBufferSize);
152*8975f5c5SAndroid Build Coastguard Worker     js::FileWriteStream os(fp, writeBuffer.data(), kBufferSize);
153*8975f5c5SAndroid Build Coastguard Worker     js::PrettyWriter<js::FileWriteStream> writer(os);
154*8975f5c5SAndroid Build Coastguard Worker     if (!doc->Accept(writer))
155*8975f5c5SAndroid Build Coastguard Worker     {
156*8975f5c5SAndroid Build Coastguard Worker         fclose(fp);
157*8975f5c5SAndroid Build Coastguard Worker         return false;
158*8975f5c5SAndroid Build Coastguard Worker     }
159*8975f5c5SAndroid Build Coastguard Worker     fclose(fp);
160*8975f5c5SAndroid Build Coastguard Worker     return true;
161*8975f5c5SAndroid Build Coastguard Worker }
162*8975f5c5SAndroid Build Coastguard Worker 
DumpTraceEventsToJSONFile(const std::vector<TraceEvent> & traceEvents,const char * outputFileName)163*8975f5c5SAndroid Build Coastguard Worker void DumpTraceEventsToJSONFile(const std::vector<TraceEvent> &traceEvents,
164*8975f5c5SAndroid Build Coastguard Worker                                const char *outputFileName)
165*8975f5c5SAndroid Build Coastguard Worker {
166*8975f5c5SAndroid Build Coastguard Worker     js::Document doc(js::kObjectType);
167*8975f5c5SAndroid Build Coastguard Worker     js::Document::AllocatorType &allocator = doc.GetAllocator();
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker     js::Value events(js::kArrayType);
170*8975f5c5SAndroid Build Coastguard Worker 
171*8975f5c5SAndroid Build Coastguard Worker     for (const TraceEvent &traceEvent : traceEvents)
172*8975f5c5SAndroid Build Coastguard Worker     {
173*8975f5c5SAndroid Build Coastguard Worker         js::Value value(js::kObjectType);
174*8975f5c5SAndroid Build Coastguard Worker 
175*8975f5c5SAndroid Build Coastguard Worker         const uint64_t microseconds = static_cast<uint64_t>(traceEvent.timestamp * 1000.0 * 1000.0);
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker         js::Document::StringRefType eventName(traceEvent.name);
178*8975f5c5SAndroid Build Coastguard Worker         js::Document::StringRefType categoryName(traceEvent.categoryName);
179*8975f5c5SAndroid Build Coastguard Worker         js::Document::StringRefType pidName(
180*8975f5c5SAndroid Build Coastguard Worker             strcmp(traceEvent.categoryName, "gpu.angle.gpu") == 0 ? "GPU" : "ANGLE");
181*8975f5c5SAndroid Build Coastguard Worker 
182*8975f5c5SAndroid Build Coastguard Worker         value.AddMember("name", eventName, allocator);
183*8975f5c5SAndroid Build Coastguard Worker         value.AddMember("cat", categoryName, allocator);
184*8975f5c5SAndroid Build Coastguard Worker         value.AddMember("ph", std::string(1, traceEvent.phase), allocator);
185*8975f5c5SAndroid Build Coastguard Worker         value.AddMember("ts", microseconds, allocator);
186*8975f5c5SAndroid Build Coastguard Worker         value.AddMember("pid", pidName, allocator);
187*8975f5c5SAndroid Build Coastguard Worker         value.AddMember("tid", traceEvent.tid, allocator);
188*8975f5c5SAndroid Build Coastguard Worker 
189*8975f5c5SAndroid Build Coastguard Worker         events.PushBack(value, allocator);
190*8975f5c5SAndroid Build Coastguard Worker     }
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker     doc.AddMember("traceEvents", events, allocator);
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker     if (WriteJsonFile(outputFileName, &doc))
195*8975f5c5SAndroid Build Coastguard Worker     {
196*8975f5c5SAndroid Build Coastguard Worker         printf("Wrote trace file to %s\n", outputFileName);
197*8975f5c5SAndroid Build Coastguard Worker     }
198*8975f5c5SAndroid Build Coastguard Worker     else
199*8975f5c5SAndroid Build Coastguard Worker     {
200*8975f5c5SAndroid Build Coastguard Worker         printf("Error writing trace file to %s\n", outputFileName);
201*8975f5c5SAndroid Build Coastguard Worker     }
202*8975f5c5SAndroid Build Coastguard Worker }
203*8975f5c5SAndroid Build Coastguard Worker 
PerfTestDebugCallback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * message,const void * userParam)204*8975f5c5SAndroid Build Coastguard Worker [[maybe_unused]] void KHRONOS_APIENTRY PerfTestDebugCallback(GLenum source,
205*8975f5c5SAndroid Build Coastguard Worker                                                              GLenum type,
206*8975f5c5SAndroid Build Coastguard Worker                                                              GLuint id,
207*8975f5c5SAndroid Build Coastguard Worker                                                              GLenum severity,
208*8975f5c5SAndroid Build Coastguard Worker                                                              GLsizei length,
209*8975f5c5SAndroid Build Coastguard Worker                                                              const GLchar *message,
210*8975f5c5SAndroid Build Coastguard Worker                                                              const void *userParam)
211*8975f5c5SAndroid Build Coastguard Worker {
212*8975f5c5SAndroid Build Coastguard Worker     // Early exit on non-errors.
213*8975f5c5SAndroid Build Coastguard Worker     if (type != GL_DEBUG_TYPE_ERROR || !userParam)
214*8975f5c5SAndroid Build Coastguard Worker     {
215*8975f5c5SAndroid Build Coastguard Worker         return;
216*8975f5c5SAndroid Build Coastguard Worker     }
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker     ANGLERenderTest *renderTest =
219*8975f5c5SAndroid Build Coastguard Worker         const_cast<ANGLERenderTest *>(reinterpret_cast<const ANGLERenderTest *>(userParam));
220*8975f5c5SAndroid Build Coastguard Worker     renderTest->onErrorMessage(message);
221*8975f5c5SAndroid Build Coastguard Worker }
222*8975f5c5SAndroid Build Coastguard Worker 
ComputeMean(const std::vector<double> & values)223*8975f5c5SAndroid Build Coastguard Worker double ComputeMean(const std::vector<double> &values)
224*8975f5c5SAndroid Build Coastguard Worker {
225*8975f5c5SAndroid Build Coastguard Worker     double sum = std::accumulate(values.begin(), values.end(), 0.0);
226*8975f5c5SAndroid Build Coastguard Worker 
227*8975f5c5SAndroid Build Coastguard Worker     double mean = sum / static_cast<double>(values.size());
228*8975f5c5SAndroid Build Coastguard Worker     return mean;
229*8975f5c5SAndroid Build Coastguard Worker }
230*8975f5c5SAndroid Build Coastguard Worker 
FinishAndCheckForContextLoss()231*8975f5c5SAndroid Build Coastguard Worker void FinishAndCheckForContextLoss()
232*8975f5c5SAndroid Build Coastguard Worker {
233*8975f5c5SAndroid Build Coastguard Worker     glFinish();
234*8975f5c5SAndroid Build Coastguard Worker     if (glGetError() == GL_CONTEXT_LOST)
235*8975f5c5SAndroid Build Coastguard Worker     {
236*8975f5c5SAndroid Build Coastguard Worker         FAIL() << "Context lost";
237*8975f5c5SAndroid Build Coastguard Worker     }
238*8975f5c5SAndroid Build Coastguard Worker }
239*8975f5c5SAndroid Build Coastguard Worker 
240*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_ANDROID)
241*8975f5c5SAndroid Build Coastguard Worker constexpr bool kHasATrace = true;
242*8975f5c5SAndroid Build Coastguard Worker 
243*8975f5c5SAndroid Build Coastguard Worker void *gLibAndroid = nullptr;
244*8975f5c5SAndroid Build Coastguard Worker bool (*gATraceIsEnabled)(void);
245*8975f5c5SAndroid Build Coastguard Worker bool (*gATraceSetCounter)(const char *counterName, int64_t counterValue);
246*8975f5c5SAndroid Build Coastguard Worker 
SetupATrace()247*8975f5c5SAndroid Build Coastguard Worker void SetupATrace()
248*8975f5c5SAndroid Build Coastguard Worker {
249*8975f5c5SAndroid Build Coastguard Worker     if (gLibAndroid == nullptr)
250*8975f5c5SAndroid Build Coastguard Worker     {
251*8975f5c5SAndroid Build Coastguard Worker         gLibAndroid       = dlopen("libandroid.so", RTLD_NOW | RTLD_LOCAL);
252*8975f5c5SAndroid Build Coastguard Worker         gATraceIsEnabled  = (decltype(gATraceIsEnabled))dlsym(gLibAndroid, "ATrace_isEnabled");
253*8975f5c5SAndroid Build Coastguard Worker         gATraceSetCounter = (decltype(gATraceSetCounter))dlsym(gLibAndroid, "ATrace_setCounter");
254*8975f5c5SAndroid Build Coastguard Worker     }
255*8975f5c5SAndroid Build Coastguard Worker }
256*8975f5c5SAndroid Build Coastguard Worker 
ATraceEnabled()257*8975f5c5SAndroid Build Coastguard Worker bool ATraceEnabled()
258*8975f5c5SAndroid Build Coastguard Worker {
259*8975f5c5SAndroid Build Coastguard Worker     return gATraceIsEnabled();
260*8975f5c5SAndroid Build Coastguard Worker }
261*8975f5c5SAndroid Build Coastguard Worker #else
262*8975f5c5SAndroid Build Coastguard Worker constexpr bool kHasATrace = false;
SetupATrace()263*8975f5c5SAndroid Build Coastguard Worker void SetupATrace() {}
ATraceEnabled()264*8975f5c5SAndroid Build Coastguard Worker bool ATraceEnabled()
265*8975f5c5SAndroid Build Coastguard Worker {
266*8975f5c5SAndroid Build Coastguard Worker     return false;
267*8975f5c5SAndroid Build Coastguard Worker }
268*8975f5c5SAndroid Build Coastguard Worker #endif
269*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
270*8975f5c5SAndroid Build Coastguard Worker 
TraceEvent(char phaseIn,const char * categoryNameIn,const char * nameIn,double timestampIn,uint32_t tidIn)271*8975f5c5SAndroid Build Coastguard Worker TraceEvent::TraceEvent(char phaseIn,
272*8975f5c5SAndroid Build Coastguard Worker                        const char *categoryNameIn,
273*8975f5c5SAndroid Build Coastguard Worker                        const char *nameIn,
274*8975f5c5SAndroid Build Coastguard Worker                        double timestampIn,
275*8975f5c5SAndroid Build Coastguard Worker                        uint32_t tidIn)
276*8975f5c5SAndroid Build Coastguard Worker     : phase(phaseIn), categoryName(categoryNameIn), name{}, timestamp(timestampIn), tid(tidIn)
277*8975f5c5SAndroid Build Coastguard Worker {
278*8975f5c5SAndroid Build Coastguard Worker     ASSERT(strlen(nameIn) < kMaxNameLen);
279*8975f5c5SAndroid Build Coastguard Worker     strcpy(name, nameIn);
280*8975f5c5SAndroid Build Coastguard Worker }
281*8975f5c5SAndroid Build Coastguard Worker 
ANGLEPerfTest(const std::string & name,const std::string & backend,const std::string & story,unsigned int iterationsPerStep,const char * units)282*8975f5c5SAndroid Build Coastguard Worker ANGLEPerfTest::ANGLEPerfTest(const std::string &name,
283*8975f5c5SAndroid Build Coastguard Worker                              const std::string &backend,
284*8975f5c5SAndroid Build Coastguard Worker                              const std::string &story,
285*8975f5c5SAndroid Build Coastguard Worker                              unsigned int iterationsPerStep,
286*8975f5c5SAndroid Build Coastguard Worker                              const char *units)
287*8975f5c5SAndroid Build Coastguard Worker     : mName(name),
288*8975f5c5SAndroid Build Coastguard Worker       mBackend(backend),
289*8975f5c5SAndroid Build Coastguard Worker       mStory(story),
290*8975f5c5SAndroid Build Coastguard Worker       mGPUTimeNs(0),
291*8975f5c5SAndroid Build Coastguard Worker       mSkipTest(false),
292*8975f5c5SAndroid Build Coastguard Worker       mStepsToRun(std::max(gStepsPerTrial, gMaxStepsPerformed)),
293*8975f5c5SAndroid Build Coastguard Worker       mTrialNumStepsPerformed(0),
294*8975f5c5SAndroid Build Coastguard Worker       mTotalNumStepsPerformed(0),
295*8975f5c5SAndroid Build Coastguard Worker       mIterationsPerStep(iterationsPerStep),
296*8975f5c5SAndroid Build Coastguard Worker       mRunning(true),
297*8975f5c5SAndroid Build Coastguard Worker       mPerfMonitor(0)
298*8975f5c5SAndroid Build Coastguard Worker {
299*8975f5c5SAndroid Build Coastguard Worker     if (mStory == "")
300*8975f5c5SAndroid Build Coastguard Worker     {
301*8975f5c5SAndroid Build Coastguard Worker         mStory = "baseline_story";
302*8975f5c5SAndroid Build Coastguard Worker     }
303*8975f5c5SAndroid Build Coastguard Worker     if (mStory[0] == '_')
304*8975f5c5SAndroid Build Coastguard Worker     {
305*8975f5c5SAndroid Build Coastguard Worker         mStory = mStory.substr(1);
306*8975f5c5SAndroid Build Coastguard Worker     }
307*8975f5c5SAndroid Build Coastguard Worker     mReporter = std::make_unique<perf_test::PerfResultReporter>(mName + mBackend, mStory);
308*8975f5c5SAndroid Build Coastguard Worker     mReporter->RegisterImportantMetric(".wall_time", units);
309*8975f5c5SAndroid Build Coastguard Worker     mReporter->RegisterImportantMetric(".cpu_time", units);
310*8975f5c5SAndroid Build Coastguard Worker     mReporter->RegisterImportantMetric(".gpu_time", units);
311*8975f5c5SAndroid Build Coastguard Worker     mReporter->RegisterFyiMetric(".trial_steps", "count");
312*8975f5c5SAndroid Build Coastguard Worker     mReporter->RegisterFyiMetric(".total_steps", "count");
313*8975f5c5SAndroid Build Coastguard Worker 
314*8975f5c5SAndroid Build Coastguard Worker     if (kHasATrace)
315*8975f5c5SAndroid Build Coastguard Worker     {
316*8975f5c5SAndroid Build Coastguard Worker         SetupATrace();
317*8975f5c5SAndroid Build Coastguard Worker     }
318*8975f5c5SAndroid Build Coastguard Worker }
319*8975f5c5SAndroid Build Coastguard Worker 
~ANGLEPerfTest()320*8975f5c5SAndroid Build Coastguard Worker ANGLEPerfTest::~ANGLEPerfTest() {}
321*8975f5c5SAndroid Build Coastguard Worker 
run()322*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::run()
323*8975f5c5SAndroid Build Coastguard Worker {
324*8975f5c5SAndroid Build Coastguard Worker     printf("running test name: \"%s\", backend: \"%s\", story: \"%s\"\n", mName.c_str(),
325*8975f5c5SAndroid Build Coastguard Worker            mBackend.c_str(), mStory.c_str());
326*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_ANDROID)
327*8975f5c5SAndroid Build Coastguard Worker     __android_log_print(ANDROID_LOG_INFO, "ANGLE",
328*8975f5c5SAndroid Build Coastguard Worker                         "running test name: \"%s\", backend: \"%s\", story: \"%s\"", mName.c_str(),
329*8975f5c5SAndroid Build Coastguard Worker                         mBackend.c_str(), mStory.c_str());
330*8975f5c5SAndroid Build Coastguard Worker #endif
331*8975f5c5SAndroid Build Coastguard Worker     if (mSkipTest)
332*8975f5c5SAndroid Build Coastguard Worker     {
333*8975f5c5SAndroid Build Coastguard Worker         GTEST_SKIP() << mSkipTestReason;
334*8975f5c5SAndroid Build Coastguard Worker         // GTEST_SKIP returns.
335*8975f5c5SAndroid Build Coastguard Worker     }
336*8975f5c5SAndroid Build Coastguard Worker 
337*8975f5c5SAndroid Build Coastguard Worker     uint32_t numTrials = OneFrame() ? 1 : gTestTrials;
338*8975f5c5SAndroid Build Coastguard Worker     if (gVerboseLogging)
339*8975f5c5SAndroid Build Coastguard Worker     {
340*8975f5c5SAndroid Build Coastguard Worker         printf("Test Trials: %d\n", static_cast<int>(numTrials));
341*8975f5c5SAndroid Build Coastguard Worker     }
342*8975f5c5SAndroid Build Coastguard Worker 
343*8975f5c5SAndroid Build Coastguard Worker     atraceCounter("TraceStage", 3);
344*8975f5c5SAndroid Build Coastguard Worker 
345*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t trial = 0; trial < numTrials; ++trial)
346*8975f5c5SAndroid Build Coastguard Worker     {
347*8975f5c5SAndroid Build Coastguard Worker         runTrial(gTrialTimeSeconds, mStepsToRun, RunTrialPolicy::RunContinuously);
348*8975f5c5SAndroid Build Coastguard Worker         processResults();
349*8975f5c5SAndroid Build Coastguard Worker         if (gVerboseLogging)
350*8975f5c5SAndroid Build Coastguard Worker         {
351*8975f5c5SAndroid Build Coastguard Worker             double trialTime = mTrialTimer.getElapsedWallClockTime();
352*8975f5c5SAndroid Build Coastguard Worker             printf("Trial %d time: %.2lf seconds.\n", trial + 1, trialTime);
353*8975f5c5SAndroid Build Coastguard Worker 
354*8975f5c5SAndroid Build Coastguard Worker             double secondsPerStep      = trialTime / static_cast<double>(mTrialNumStepsPerformed);
355*8975f5c5SAndroid Build Coastguard Worker             double secondsPerIteration = secondsPerStep / static_cast<double>(mIterationsPerStep);
356*8975f5c5SAndroid Build Coastguard Worker             mTestTrialResults.push_back(secondsPerIteration * 1000.0);
357*8975f5c5SAndroid Build Coastguard Worker         }
358*8975f5c5SAndroid Build Coastguard Worker     }
359*8975f5c5SAndroid Build Coastguard Worker 
360*8975f5c5SAndroid Build Coastguard Worker     atraceCounter("TraceStage", 0);
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker     if (gVerboseLogging && !mTestTrialResults.empty())
363*8975f5c5SAndroid Build Coastguard Worker     {
364*8975f5c5SAndroid Build Coastguard Worker         double numResults = static_cast<double>(mTestTrialResults.size());
365*8975f5c5SAndroid Build Coastguard Worker         double mean       = ComputeMean(mTestTrialResults);
366*8975f5c5SAndroid Build Coastguard Worker 
367*8975f5c5SAndroid Build Coastguard Worker         double variance = 0;
368*8975f5c5SAndroid Build Coastguard Worker         for (double trialResult : mTestTrialResults)
369*8975f5c5SAndroid Build Coastguard Worker         {
370*8975f5c5SAndroid Build Coastguard Worker             double difference = trialResult - mean;
371*8975f5c5SAndroid Build Coastguard Worker             variance += difference * difference;
372*8975f5c5SAndroid Build Coastguard Worker         }
373*8975f5c5SAndroid Build Coastguard Worker         variance /= numResults;
374*8975f5c5SAndroid Build Coastguard Worker 
375*8975f5c5SAndroid Build Coastguard Worker         double standardDeviation      = std::sqrt(variance);
376*8975f5c5SAndroid Build Coastguard Worker         double coefficientOfVariation = standardDeviation / mean;
377*8975f5c5SAndroid Build Coastguard Worker 
378*8975f5c5SAndroid Build Coastguard Worker         if (mean < 0.001)
379*8975f5c5SAndroid Build Coastguard Worker         {
380*8975f5c5SAndroid Build Coastguard Worker             printf("Mean result time: %.4lf ns.\n", mean * 1000.0);
381*8975f5c5SAndroid Build Coastguard Worker         }
382*8975f5c5SAndroid Build Coastguard Worker         else
383*8975f5c5SAndroid Build Coastguard Worker         {
384*8975f5c5SAndroid Build Coastguard Worker             printf("Mean result time: %.4lf ms.\n", mean);
385*8975f5c5SAndroid Build Coastguard Worker         }
386*8975f5c5SAndroid Build Coastguard Worker         printf("Coefficient of variation: %.2lf%%\n", coefficientOfVariation * 100.0);
387*8975f5c5SAndroid Build Coastguard Worker     }
388*8975f5c5SAndroid Build Coastguard Worker }
389*8975f5c5SAndroid Build Coastguard Worker 
runTrial(double maxRunTime,int maxStepsToRun,RunTrialPolicy runPolicy)390*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::runTrial(double maxRunTime, int maxStepsToRun, RunTrialPolicy runPolicy)
391*8975f5c5SAndroid Build Coastguard Worker {
392*8975f5c5SAndroid Build Coastguard Worker     mTrialNumStepsPerformed = 0;
393*8975f5c5SAndroid Build Coastguard Worker     mRunning                = true;
394*8975f5c5SAndroid Build Coastguard Worker     mGPUTimeNs              = 0;
395*8975f5c5SAndroid Build Coastguard Worker     int stepAlignment       = getStepAlignment();
396*8975f5c5SAndroid Build Coastguard Worker     mTrialTimer.start();
397*8975f5c5SAndroid Build Coastguard Worker     startTest();
398*8975f5c5SAndroid Build Coastguard Worker 
399*8975f5c5SAndroid Build Coastguard Worker     int loopStepsPerformed  = 0;
400*8975f5c5SAndroid Build Coastguard Worker     double lastLoopWallTime = 0;
401*8975f5c5SAndroid Build Coastguard Worker     while (mRunning)
402*8975f5c5SAndroid Build Coastguard Worker     {
403*8975f5c5SAndroid Build Coastguard Worker         // When ATrace enabled, track average frame time before the first frame of each trace loop.
404*8975f5c5SAndroid Build Coastguard Worker         if (ATraceEnabled() && stepAlignment > 1 && runPolicy == RunTrialPolicy::RunContinuously &&
405*8975f5c5SAndroid Build Coastguard Worker             mTrialNumStepsPerformed % stepAlignment == 0)
406*8975f5c5SAndroid Build Coastguard Worker         {
407*8975f5c5SAndroid Build Coastguard Worker             double wallTime = mTrialTimer.getElapsedWallClockTime();
408*8975f5c5SAndroid Build Coastguard Worker             if (loopStepsPerformed > 0)  // 0 at the first frame of the first loop
409*8975f5c5SAndroid Build Coastguard Worker             {
410*8975f5c5SAndroid Build Coastguard Worker                 int frameTimeAvgUs = int(1e6 * (wallTime - lastLoopWallTime) / loopStepsPerformed);
411*8975f5c5SAndroid Build Coastguard Worker                 atraceCounter("TraceLoopFrameTimeAvgUs", frameTimeAvgUs);
412*8975f5c5SAndroid Build Coastguard Worker                 loopStepsPerformed = 0;
413*8975f5c5SAndroid Build Coastguard Worker             }
414*8975f5c5SAndroid Build Coastguard Worker             lastLoopWallTime = wallTime;
415*8975f5c5SAndroid Build Coastguard Worker         }
416*8975f5c5SAndroid Build Coastguard Worker 
417*8975f5c5SAndroid Build Coastguard Worker         // Only stop on aligned steps or in a few special case modes
418*8975f5c5SAndroid Build Coastguard Worker         if (mTrialNumStepsPerformed % stepAlignment == 0 || gStepsPerTrial == 1 || gRunToKeyFrame ||
419*8975f5c5SAndroid Build Coastguard Worker             gMaxStepsPerformed != kDefaultMaxStepsPerformed)
420*8975f5c5SAndroid Build Coastguard Worker         {
421*8975f5c5SAndroid Build Coastguard Worker             if (gMaxStepsPerformed > 0 && mTotalNumStepsPerformed >= gMaxStepsPerformed)
422*8975f5c5SAndroid Build Coastguard Worker             {
423*8975f5c5SAndroid Build Coastguard Worker                 if (gVerboseLogging)
424*8975f5c5SAndroid Build Coastguard Worker                 {
425*8975f5c5SAndroid Build Coastguard Worker                     printf("Stopping test after %d total steps.\n", mTotalNumStepsPerformed);
426*8975f5c5SAndroid Build Coastguard Worker                 }
427*8975f5c5SAndroid Build Coastguard Worker                 mRunning = false;
428*8975f5c5SAndroid Build Coastguard Worker                 break;
429*8975f5c5SAndroid Build Coastguard Worker             }
430*8975f5c5SAndroid Build Coastguard Worker             if (mTrialTimer.getElapsedWallClockTime() > maxRunTime)
431*8975f5c5SAndroid Build Coastguard Worker             {
432*8975f5c5SAndroid Build Coastguard Worker                 if (gVerboseLogging)
433*8975f5c5SAndroid Build Coastguard Worker                 {
434*8975f5c5SAndroid Build Coastguard Worker                     printf("Stopping test after %.2lf seconds.\n",
435*8975f5c5SAndroid Build Coastguard Worker                            mTrialTimer.getElapsedWallClockTime());
436*8975f5c5SAndroid Build Coastguard Worker                 }
437*8975f5c5SAndroid Build Coastguard Worker                 mRunning = false;
438*8975f5c5SAndroid Build Coastguard Worker                 break;
439*8975f5c5SAndroid Build Coastguard Worker             }
440*8975f5c5SAndroid Build Coastguard Worker             if (mTrialNumStepsPerformed >= maxStepsToRun)
441*8975f5c5SAndroid Build Coastguard Worker             {
442*8975f5c5SAndroid Build Coastguard Worker                 if (gVerboseLogging)
443*8975f5c5SAndroid Build Coastguard Worker                 {
444*8975f5c5SAndroid Build Coastguard Worker                     printf("Stopping test after %d trial steps.\n", mTrialNumStepsPerformed);
445*8975f5c5SAndroid Build Coastguard Worker                 }
446*8975f5c5SAndroid Build Coastguard Worker                 mRunning = false;
447*8975f5c5SAndroid Build Coastguard Worker                 break;
448*8975f5c5SAndroid Build Coastguard Worker             }
449*8975f5c5SAndroid Build Coastguard Worker         }
450*8975f5c5SAndroid Build Coastguard Worker 
451*8975f5c5SAndroid Build Coastguard Worker         step();
452*8975f5c5SAndroid Build Coastguard Worker 
453*8975f5c5SAndroid Build Coastguard Worker         if (runPolicy == RunTrialPolicy::FinishEveryStep)
454*8975f5c5SAndroid Build Coastguard Worker         {
455*8975f5c5SAndroid Build Coastguard Worker             FinishAndCheckForContextLoss();
456*8975f5c5SAndroid Build Coastguard Worker         }
457*8975f5c5SAndroid Build Coastguard Worker 
458*8975f5c5SAndroid Build Coastguard Worker         if (mRunning)
459*8975f5c5SAndroid Build Coastguard Worker         {
460*8975f5c5SAndroid Build Coastguard Worker             mTrialNumStepsPerformed++;
461*8975f5c5SAndroid Build Coastguard Worker             mTotalNumStepsPerformed++;
462*8975f5c5SAndroid Build Coastguard Worker             loopStepsPerformed++;
463*8975f5c5SAndroid Build Coastguard Worker         }
464*8975f5c5SAndroid Build Coastguard Worker 
465*8975f5c5SAndroid Build Coastguard Worker         if ((mTotalNumStepsPerformed % kNumberOfStepsPerformedToComputeGPUTime) == 0)
466*8975f5c5SAndroid Build Coastguard Worker         {
467*8975f5c5SAndroid Build Coastguard Worker             computeGPUTime();
468*8975f5c5SAndroid Build Coastguard Worker         }
469*8975f5c5SAndroid Build Coastguard Worker     }
470*8975f5c5SAndroid Build Coastguard Worker 
471*8975f5c5SAndroid Build Coastguard Worker     if (runPolicy == RunTrialPolicy::RunContinuously)
472*8975f5c5SAndroid Build Coastguard Worker     {
473*8975f5c5SAndroid Build Coastguard Worker         atraceCounter("TraceLoopFrameTimeAvgUs", 0);
474*8975f5c5SAndroid Build Coastguard Worker     }
475*8975f5c5SAndroid Build Coastguard Worker     finishTest();
476*8975f5c5SAndroid Build Coastguard Worker     mTrialTimer.stop();
477*8975f5c5SAndroid Build Coastguard Worker     computeGPUTime();
478*8975f5c5SAndroid Build Coastguard Worker }
479*8975f5c5SAndroid Build Coastguard Worker 
SetUp()480*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::SetUp()
481*8975f5c5SAndroid Build Coastguard Worker {
482*8975f5c5SAndroid Build Coastguard Worker     if (gWarmup)
483*8975f5c5SAndroid Build Coastguard Worker     {
484*8975f5c5SAndroid Build Coastguard Worker         atraceCounter("TraceStage", 1);
485*8975f5c5SAndroid Build Coastguard Worker 
486*8975f5c5SAndroid Build Coastguard Worker         // Trace tests run with glFinish for a loop (getStepAlignment == frameCount).
487*8975f5c5SAndroid Build Coastguard Worker         int warmupSteps = getStepAlignment();
488*8975f5c5SAndroid Build Coastguard Worker         if (gVerboseLogging)
489*8975f5c5SAndroid Build Coastguard Worker         {
490*8975f5c5SAndroid Build Coastguard Worker             printf("Warmup: %d steps\n", warmupSteps);
491*8975f5c5SAndroid Build Coastguard Worker         }
492*8975f5c5SAndroid Build Coastguard Worker 
493*8975f5c5SAndroid Build Coastguard Worker         Timer warmupTimer;
494*8975f5c5SAndroid Build Coastguard Worker         warmupTimer.start();
495*8975f5c5SAndroid Build Coastguard Worker 
496*8975f5c5SAndroid Build Coastguard Worker         runTrial(gTrialTimeSeconds, warmupSteps, RunTrialPolicy::FinishEveryStep);
497*8975f5c5SAndroid Build Coastguard Worker 
498*8975f5c5SAndroid Build Coastguard Worker         if (warmupSteps > 1)  // trace tests only: getStepAlignment() is 1 otherwise
499*8975f5c5SAndroid Build Coastguard Worker         {
500*8975f5c5SAndroid Build Coastguard Worker             atraceCounter("TraceStage", 2);
501*8975f5c5SAndroid Build Coastguard Worker 
502*8975f5c5SAndroid Build Coastguard Worker             // Short traces (e.g. 10 frames) have some spikes after the first loop b/308975999
503*8975f5c5SAndroid Build Coastguard Worker             const double kMinWarmupTime = 1.5;
504*8975f5c5SAndroid Build Coastguard Worker             double remainingTime        = kMinWarmupTime - warmupTimer.getElapsedWallClockTime();
505*8975f5c5SAndroid Build Coastguard Worker             if (remainingTime > 0)
506*8975f5c5SAndroid Build Coastguard Worker             {
507*8975f5c5SAndroid Build Coastguard Worker                 printf("Warmup: Looping for remaining warmup time (%.2f seconds).\n",
508*8975f5c5SAndroid Build Coastguard Worker                        remainingTime);
509*8975f5c5SAndroid Build Coastguard Worker                 runTrial(remainingTime, std::numeric_limits<int>::max(),
510*8975f5c5SAndroid Build Coastguard Worker                          RunTrialPolicy::RunContinuouslyWarmup);
511*8975f5c5SAndroid Build Coastguard Worker             }
512*8975f5c5SAndroid Build Coastguard Worker         }
513*8975f5c5SAndroid Build Coastguard Worker 
514*8975f5c5SAndroid Build Coastguard Worker         if (gVerboseLogging)
515*8975f5c5SAndroid Build Coastguard Worker         {
516*8975f5c5SAndroid Build Coastguard Worker             printf("Warmup took %.2lf seconds.\n", warmupTimer.getElapsedWallClockTime());
517*8975f5c5SAndroid Build Coastguard Worker         }
518*8975f5c5SAndroid Build Coastguard Worker     }
519*8975f5c5SAndroid Build Coastguard Worker }
520*8975f5c5SAndroid Build Coastguard Worker 
TearDown()521*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::TearDown() {}
522*8975f5c5SAndroid Build Coastguard Worker 
recordIntegerMetric(const char * metric,size_t value,const std::string & units)523*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::recordIntegerMetric(const char *metric, size_t value, const std::string &units)
524*8975f5c5SAndroid Build Coastguard Worker {
525*8975f5c5SAndroid Build Coastguard Worker     // Prints "RESULT ..." to stdout
526*8975f5c5SAndroid Build Coastguard Worker     mReporter->AddResult(metric, value);
527*8975f5c5SAndroid Build Coastguard Worker 
528*8975f5c5SAndroid Build Coastguard Worker     // Saves results to file if enabled
529*8975f5c5SAndroid Build Coastguard Worker     TestSuite::GetMetricWriter().writeInfo(mName, mBackend, mStory, metric, units);
530*8975f5c5SAndroid Build Coastguard Worker     TestSuite::GetMetricWriter().writeIntegerValue(value);
531*8975f5c5SAndroid Build Coastguard Worker }
532*8975f5c5SAndroid Build Coastguard Worker 
recordDoubleMetric(const char * metric,double value,const std::string & units)533*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::recordDoubleMetric(const char *metric, double value, const std::string &units)
534*8975f5c5SAndroid Build Coastguard Worker {
535*8975f5c5SAndroid Build Coastguard Worker     // Prints "RESULT ..." to stdout
536*8975f5c5SAndroid Build Coastguard Worker     mReporter->AddResult(metric, value);
537*8975f5c5SAndroid Build Coastguard Worker 
538*8975f5c5SAndroid Build Coastguard Worker     // Saves results to file if enabled
539*8975f5c5SAndroid Build Coastguard Worker     TestSuite::GetMetricWriter().writeInfo(mName, mBackend, mStory, metric, units);
540*8975f5c5SAndroid Build Coastguard Worker     TestSuite::GetMetricWriter().writeDoubleValue(value);
541*8975f5c5SAndroid Build Coastguard Worker }
542*8975f5c5SAndroid Build Coastguard Worker 
addHistogramSample(const char * metric,double value,const std::string & units)543*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::addHistogramSample(const char *metric, double value, const std::string &units)
544*8975f5c5SAndroid Build Coastguard Worker {
545*8975f5c5SAndroid Build Coastguard Worker     std::string measurement = mName + mBackend + metric;
546*8975f5c5SAndroid Build Coastguard Worker     // Output histogram JSON set format if enabled.
547*8975f5c5SAndroid Build Coastguard Worker     TestSuite::GetInstance()->addHistogramSample(measurement, mStory, value, units);
548*8975f5c5SAndroid Build Coastguard Worker }
549*8975f5c5SAndroid Build Coastguard Worker 
processResults()550*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::processResults()
551*8975f5c5SAndroid Build Coastguard Worker {
552*8975f5c5SAndroid Build Coastguard Worker     processClockResult(".cpu_time", mTrialTimer.getElapsedCpuTime());
553*8975f5c5SAndroid Build Coastguard Worker     processClockResult(".wall_time", mTrialTimer.getElapsedWallClockTime());
554*8975f5c5SAndroid Build Coastguard Worker 
555*8975f5c5SAndroid Build Coastguard Worker     if (mGPUTimeNs > 0)
556*8975f5c5SAndroid Build Coastguard Worker     {
557*8975f5c5SAndroid Build Coastguard Worker         processClockResult(".gpu_time", mGPUTimeNs * 1e-9);
558*8975f5c5SAndroid Build Coastguard Worker     }
559*8975f5c5SAndroid Build Coastguard Worker 
560*8975f5c5SAndroid Build Coastguard Worker     if (gVerboseLogging)
561*8975f5c5SAndroid Build Coastguard Worker     {
562*8975f5c5SAndroid Build Coastguard Worker         double fps = static_cast<double>(mTrialNumStepsPerformed * mIterationsPerStep) /
563*8975f5c5SAndroid Build Coastguard Worker                      mTrialTimer.getElapsedWallClockTime();
564*8975f5c5SAndroid Build Coastguard Worker         printf("Ran %0.2lf iterations per second\n", fps);
565*8975f5c5SAndroid Build Coastguard Worker     }
566*8975f5c5SAndroid Build Coastguard Worker 
567*8975f5c5SAndroid Build Coastguard Worker     mReporter->AddResult(".trial_steps", static_cast<size_t>(mTrialNumStepsPerformed));
568*8975f5c5SAndroid Build Coastguard Worker     mReporter->AddResult(".total_steps", static_cast<size_t>(mTotalNumStepsPerformed));
569*8975f5c5SAndroid Build Coastguard Worker 
570*8975f5c5SAndroid Build Coastguard Worker     if (!mProcessMemoryUsageKBSamples.empty())
571*8975f5c5SAndroid Build Coastguard Worker     {
572*8975f5c5SAndroid Build Coastguard Worker         std::sort(mProcessMemoryUsageKBSamples.begin(), mProcessMemoryUsageKBSamples.end());
573*8975f5c5SAndroid Build Coastguard Worker 
574*8975f5c5SAndroid Build Coastguard Worker         // Compute median.
575*8975f5c5SAndroid Build Coastguard Worker         size_t medianIndex      = mProcessMemoryUsageKBSamples.size() / 2;
576*8975f5c5SAndroid Build Coastguard Worker         uint64_t medianMemoryKB = mProcessMemoryUsageKBSamples[medianIndex];
577*8975f5c5SAndroid Build Coastguard Worker         auto peakMemoryIterator = std::max_element(mProcessMemoryUsageKBSamples.begin(),
578*8975f5c5SAndroid Build Coastguard Worker                                                    mProcessMemoryUsageKBSamples.end());
579*8975f5c5SAndroid Build Coastguard Worker         uint64_t peakMemoryKB   = *peakMemoryIterator;
580*8975f5c5SAndroid Build Coastguard Worker 
581*8975f5c5SAndroid Build Coastguard Worker         processMemoryResult(kMedianMemoryMetric, medianMemoryKB);
582*8975f5c5SAndroid Build Coastguard Worker         processMemoryResult(kPeakMemoryMetric, peakMemoryKB);
583*8975f5c5SAndroid Build Coastguard Worker     }
584*8975f5c5SAndroid Build Coastguard Worker 
585*8975f5c5SAndroid Build Coastguard Worker     for (const auto &iter : mPerfCounterInfo)
586*8975f5c5SAndroid Build Coastguard Worker     {
587*8975f5c5SAndroid Build Coastguard Worker         const std::string &counterName = iter.second.name;
588*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLuint64> samples  = iter.second.samples;
589*8975f5c5SAndroid Build Coastguard Worker 
590*8975f5c5SAndroid Build Coastguard Worker         // Median
591*8975f5c5SAndroid Build Coastguard Worker         {
592*8975f5c5SAndroid Build Coastguard Worker             size_t midpoint = samples.size() / 2;
593*8975f5c5SAndroid Build Coastguard Worker             std::nth_element(samples.begin(), samples.begin() + midpoint, samples.end());
594*8975f5c5SAndroid Build Coastguard Worker 
595*8975f5c5SAndroid Build Coastguard Worker             std::string medianName = "." + counterName + "_median";
596*8975f5c5SAndroid Build Coastguard Worker             recordIntegerMetric(medianName.c_str(), static_cast<size_t>(samples[midpoint]),
597*8975f5c5SAndroid Build Coastguard Worker                                 "count");
598*8975f5c5SAndroid Build Coastguard Worker             addHistogramSample(medianName.c_str(), static_cast<double>(samples[midpoint]), "count");
599*8975f5c5SAndroid Build Coastguard Worker         }
600*8975f5c5SAndroid Build Coastguard Worker 
601*8975f5c5SAndroid Build Coastguard Worker         // Maximum
602*8975f5c5SAndroid Build Coastguard Worker         {
603*8975f5c5SAndroid Build Coastguard Worker             const auto &maxIt = std::max_element(samples.begin(), samples.end());
604*8975f5c5SAndroid Build Coastguard Worker 
605*8975f5c5SAndroid Build Coastguard Worker             std::string maxName = "." + counterName + "_max";
606*8975f5c5SAndroid Build Coastguard Worker             recordIntegerMetric(maxName.c_str(), static_cast<size_t>(*maxIt), "count");
607*8975f5c5SAndroid Build Coastguard Worker             addHistogramSample(maxName.c_str(), static_cast<double>(*maxIt), "count");
608*8975f5c5SAndroid Build Coastguard Worker         }
609*8975f5c5SAndroid Build Coastguard Worker 
610*8975f5c5SAndroid Build Coastguard Worker         // Sum
611*8975f5c5SAndroid Build Coastguard Worker         {
612*8975f5c5SAndroid Build Coastguard Worker             GLuint64 sum =
613*8975f5c5SAndroid Build Coastguard Worker                 std::accumulate(samples.begin(), samples.end(), static_cast<GLuint64>(0));
614*8975f5c5SAndroid Build Coastguard Worker 
615*8975f5c5SAndroid Build Coastguard Worker             std::string sumName = "." + counterName + "_max";
616*8975f5c5SAndroid Build Coastguard Worker             recordIntegerMetric(sumName.c_str(), static_cast<size_t>(sum), "count");
617*8975f5c5SAndroid Build Coastguard Worker             addHistogramSample(sumName.c_str(), static_cast<double>(sum), "count");
618*8975f5c5SAndroid Build Coastguard Worker         }
619*8975f5c5SAndroid Build Coastguard Worker     }
620*8975f5c5SAndroid Build Coastguard Worker }
621*8975f5c5SAndroid Build Coastguard Worker 
processClockResult(const char * metric,double resultSeconds)622*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::processClockResult(const char *metric, double resultSeconds)
623*8975f5c5SAndroid Build Coastguard Worker {
624*8975f5c5SAndroid Build Coastguard Worker     double secondsPerStep      = resultSeconds / static_cast<double>(mTrialNumStepsPerformed);
625*8975f5c5SAndroid Build Coastguard Worker     double secondsPerIteration = secondsPerStep / static_cast<double>(mIterationsPerStep);
626*8975f5c5SAndroid Build Coastguard Worker 
627*8975f5c5SAndroid Build Coastguard Worker     perf_test::MetricInfo metricInfo;
628*8975f5c5SAndroid Build Coastguard Worker     std::string units;
629*8975f5c5SAndroid Build Coastguard Worker     bool foundMetric = mReporter->GetMetricInfo(metric, &metricInfo);
630*8975f5c5SAndroid Build Coastguard Worker     if (!foundMetric)
631*8975f5c5SAndroid Build Coastguard Worker     {
632*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Error getting metric info for %s.\n", metric);
633*8975f5c5SAndroid Build Coastguard Worker         return;
634*8975f5c5SAndroid Build Coastguard Worker     }
635*8975f5c5SAndroid Build Coastguard Worker     units = metricInfo.units;
636*8975f5c5SAndroid Build Coastguard Worker 
637*8975f5c5SAndroid Build Coastguard Worker     double result;
638*8975f5c5SAndroid Build Coastguard Worker 
639*8975f5c5SAndroid Build Coastguard Worker     if (units == "ms")
640*8975f5c5SAndroid Build Coastguard Worker     {
641*8975f5c5SAndroid Build Coastguard Worker         result = secondsPerIteration * kMilliSecondsPerSecond;
642*8975f5c5SAndroid Build Coastguard Worker     }
643*8975f5c5SAndroid Build Coastguard Worker     else if (units == "us")
644*8975f5c5SAndroid Build Coastguard Worker     {
645*8975f5c5SAndroid Build Coastguard Worker         result = secondsPerIteration * kMicroSecondsPerSecond;
646*8975f5c5SAndroid Build Coastguard Worker     }
647*8975f5c5SAndroid Build Coastguard Worker     else
648*8975f5c5SAndroid Build Coastguard Worker     {
649*8975f5c5SAndroid Build Coastguard Worker         result = secondsPerIteration * kNanoSecondsPerSecond;
650*8975f5c5SAndroid Build Coastguard Worker     }
651*8975f5c5SAndroid Build Coastguard Worker     recordDoubleMetric(metric, result, units);
652*8975f5c5SAndroid Build Coastguard Worker     addHistogramSample(metric, secondsPerIteration * kMilliSecondsPerSecond,
653*8975f5c5SAndroid Build Coastguard Worker                        "msBestFitFormat_smallerIsBetter");
654*8975f5c5SAndroid Build Coastguard Worker }
655*8975f5c5SAndroid Build Coastguard Worker 
processMemoryResult(const char * metric,uint64_t resultKB)656*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::processMemoryResult(const char *metric, uint64_t resultKB)
657*8975f5c5SAndroid Build Coastguard Worker {
658*8975f5c5SAndroid Build Coastguard Worker     perf_test::MetricInfo metricInfo;
659*8975f5c5SAndroid Build Coastguard Worker     if (!mReporter->GetMetricInfo(metric, &metricInfo))
660*8975f5c5SAndroid Build Coastguard Worker     {
661*8975f5c5SAndroid Build Coastguard Worker         mReporter->RegisterImportantMetric(metric, "sizeInBytes");
662*8975f5c5SAndroid Build Coastguard Worker     }
663*8975f5c5SAndroid Build Coastguard Worker 
664*8975f5c5SAndroid Build Coastguard Worker     recordIntegerMetric(metric, static_cast<size_t>(resultKB * 1000), "sizeInBytes");
665*8975f5c5SAndroid Build Coastguard Worker     addHistogramSample(metric, static_cast<double>(resultKB) * 1000.0,
666*8975f5c5SAndroid Build Coastguard Worker                        "sizeInBytes_smallerIsBetter");
667*8975f5c5SAndroid Build Coastguard Worker }
668*8975f5c5SAndroid Build Coastguard Worker 
normalizedTime(size_t value) const669*8975f5c5SAndroid Build Coastguard Worker double ANGLEPerfTest::normalizedTime(size_t value) const
670*8975f5c5SAndroid Build Coastguard Worker {
671*8975f5c5SAndroid Build Coastguard Worker     return static_cast<double>(value) / static_cast<double>(mTrialNumStepsPerformed);
672*8975f5c5SAndroid Build Coastguard Worker }
673*8975f5c5SAndroid Build Coastguard Worker 
getStepAlignment() const674*8975f5c5SAndroid Build Coastguard Worker int ANGLEPerfTest::getStepAlignment() const
675*8975f5c5SAndroid Build Coastguard Worker {
676*8975f5c5SAndroid Build Coastguard Worker     // Default: No special alignment rules.
677*8975f5c5SAndroid Build Coastguard Worker     return 1;
678*8975f5c5SAndroid Build Coastguard Worker }
679*8975f5c5SAndroid Build Coastguard Worker 
atraceCounter(const char * counterName,int64_t counterValue)680*8975f5c5SAndroid Build Coastguard Worker void ANGLEPerfTest::atraceCounter(const char *counterName, int64_t counterValue)
681*8975f5c5SAndroid Build Coastguard Worker {
682*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_ANDROID)
683*8975f5c5SAndroid Build Coastguard Worker     if (ATraceEnabled())
684*8975f5c5SAndroid Build Coastguard Worker     {
685*8975f5c5SAndroid Build Coastguard Worker         gATraceSetCounter(counterName, counterValue);
686*8975f5c5SAndroid Build Coastguard Worker     }
687*8975f5c5SAndroid Build Coastguard Worker #endif
688*8975f5c5SAndroid Build Coastguard Worker }
689*8975f5c5SAndroid Build Coastguard Worker 
RenderTestParams()690*8975f5c5SAndroid Build Coastguard Worker RenderTestParams::RenderTestParams()
691*8975f5c5SAndroid Build Coastguard Worker {
692*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_DEBUG_LAYERS_ENABLED)
693*8975f5c5SAndroid Build Coastguard Worker     eglParameters.debugLayersEnabled = true;
694*8975f5c5SAndroid Build Coastguard Worker #else
695*8975f5c5SAndroid Build Coastguard Worker     eglParameters.debugLayersEnabled = false;
696*8975f5c5SAndroid Build Coastguard Worker #endif
697*8975f5c5SAndroid Build Coastguard Worker }
698*8975f5c5SAndroid Build Coastguard Worker 
backend() const699*8975f5c5SAndroid Build Coastguard Worker std::string RenderTestParams::backend() const
700*8975f5c5SAndroid Build Coastguard Worker {
701*8975f5c5SAndroid Build Coastguard Worker     std::stringstream strstr;
702*8975f5c5SAndroid Build Coastguard Worker 
703*8975f5c5SAndroid Build Coastguard Worker     switch (driver)
704*8975f5c5SAndroid Build Coastguard Worker     {
705*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::AngleEGL:
706*8975f5c5SAndroid Build Coastguard Worker             break;
707*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::AngleVulkanSecondariesEGL:
708*8975f5c5SAndroid Build Coastguard Worker             strstr << "_vulkan_secondaries";
709*8975f5c5SAndroid Build Coastguard Worker             break;
710*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::SystemWGL:
711*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::SystemEGL:
712*8975f5c5SAndroid Build Coastguard Worker             strstr << "_native";
713*8975f5c5SAndroid Build Coastguard Worker             break;
714*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::ZinkEGL:
715*8975f5c5SAndroid Build Coastguard Worker             strstr << "_zink";
716*8975f5c5SAndroid Build Coastguard Worker             break;
717*8975f5c5SAndroid Build Coastguard Worker         default:
718*8975f5c5SAndroid Build Coastguard Worker             assert(0);
719*8975f5c5SAndroid Build Coastguard Worker             return "_unk";
720*8975f5c5SAndroid Build Coastguard Worker     }
721*8975f5c5SAndroid Build Coastguard Worker 
722*8975f5c5SAndroid Build Coastguard Worker     switch (getRenderer())
723*8975f5c5SAndroid Build Coastguard Worker     {
724*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
725*8975f5c5SAndroid Build Coastguard Worker             break;
726*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
727*8975f5c5SAndroid Build Coastguard Worker             strstr << "_d3d11";
728*8975f5c5SAndroid Build Coastguard Worker             break;
729*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
730*8975f5c5SAndroid Build Coastguard Worker             strstr << "_d3d9";
731*8975f5c5SAndroid Build Coastguard Worker             break;
732*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
733*8975f5c5SAndroid Build Coastguard Worker             strstr << "_gl";
734*8975f5c5SAndroid Build Coastguard Worker             break;
735*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
736*8975f5c5SAndroid Build Coastguard Worker             strstr << "_gles";
737*8975f5c5SAndroid Build Coastguard Worker             break;
738*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
739*8975f5c5SAndroid Build Coastguard Worker             strstr << "_vulkan";
740*8975f5c5SAndroid Build Coastguard Worker             break;
741*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
742*8975f5c5SAndroid Build Coastguard Worker             strstr << "_metal";
743*8975f5c5SAndroid Build Coastguard Worker             break;
744*8975f5c5SAndroid Build Coastguard Worker         default:
745*8975f5c5SAndroid Build Coastguard Worker             assert(0);
746*8975f5c5SAndroid Build Coastguard Worker             return "_unk";
747*8975f5c5SAndroid Build Coastguard Worker     }
748*8975f5c5SAndroid Build Coastguard Worker 
749*8975f5c5SAndroid Build Coastguard Worker     switch (eglParameters.deviceType)
750*8975f5c5SAndroid Build Coastguard Worker     {
751*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
752*8975f5c5SAndroid Build Coastguard Worker             strstr << "_null";
753*8975f5c5SAndroid Build Coastguard Worker             break;
754*8975f5c5SAndroid Build Coastguard Worker         case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE:
755*8975f5c5SAndroid Build Coastguard Worker             strstr << "_swiftshader";
756*8975f5c5SAndroid Build Coastguard Worker             break;
757*8975f5c5SAndroid Build Coastguard Worker         default:
758*8975f5c5SAndroid Build Coastguard Worker             break;
759*8975f5c5SAndroid Build Coastguard Worker     }
760*8975f5c5SAndroid Build Coastguard Worker 
761*8975f5c5SAndroid Build Coastguard Worker     return strstr.str();
762*8975f5c5SAndroid Build Coastguard Worker }
763*8975f5c5SAndroid Build Coastguard Worker 
story() const764*8975f5c5SAndroid Build Coastguard Worker std::string RenderTestParams::story() const
765*8975f5c5SAndroid Build Coastguard Worker {
766*8975f5c5SAndroid Build Coastguard Worker     std::stringstream strstr;
767*8975f5c5SAndroid Build Coastguard Worker 
768*8975f5c5SAndroid Build Coastguard Worker     switch (surfaceType)
769*8975f5c5SAndroid Build Coastguard Worker     {
770*8975f5c5SAndroid Build Coastguard Worker         case SurfaceType::Window:
771*8975f5c5SAndroid Build Coastguard Worker             break;
772*8975f5c5SAndroid Build Coastguard Worker         case SurfaceType::WindowWithVSync:
773*8975f5c5SAndroid Build Coastguard Worker             strstr << "_vsync";
774*8975f5c5SAndroid Build Coastguard Worker             break;
775*8975f5c5SAndroid Build Coastguard Worker         case SurfaceType::Offscreen:
776*8975f5c5SAndroid Build Coastguard Worker             strstr << "_offscreen";
777*8975f5c5SAndroid Build Coastguard Worker             break;
778*8975f5c5SAndroid Build Coastguard Worker         default:
779*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
780*8975f5c5SAndroid Build Coastguard Worker             return "";
781*8975f5c5SAndroid Build Coastguard Worker     }
782*8975f5c5SAndroid Build Coastguard Worker 
783*8975f5c5SAndroid Build Coastguard Worker     if (multisample)
784*8975f5c5SAndroid Build Coastguard Worker     {
785*8975f5c5SAndroid Build Coastguard Worker         strstr << "_" << samples << "_samples";
786*8975f5c5SAndroid Build Coastguard Worker     }
787*8975f5c5SAndroid Build Coastguard Worker 
788*8975f5c5SAndroid Build Coastguard Worker     return strstr.str();
789*8975f5c5SAndroid Build Coastguard Worker }
790*8975f5c5SAndroid Build Coastguard Worker 
backendAndStory() const791*8975f5c5SAndroid Build Coastguard Worker std::string RenderTestParams::backendAndStory() const
792*8975f5c5SAndroid Build Coastguard Worker {
793*8975f5c5SAndroid Build Coastguard Worker     return backend() + story();
794*8975f5c5SAndroid Build Coastguard Worker }
795*8975f5c5SAndroid Build Coastguard Worker 
ANGLERenderTest(const std::string & name,const RenderTestParams & testParams,const char * units)796*8975f5c5SAndroid Build Coastguard Worker ANGLERenderTest::ANGLERenderTest(const std::string &name,
797*8975f5c5SAndroid Build Coastguard Worker                                  const RenderTestParams &testParams,
798*8975f5c5SAndroid Build Coastguard Worker                                  const char *units)
799*8975f5c5SAndroid Build Coastguard Worker     : ANGLEPerfTest(name,
800*8975f5c5SAndroid Build Coastguard Worker                     testParams.backend(),
801*8975f5c5SAndroid Build Coastguard Worker                     testParams.story(),
802*8975f5c5SAndroid Build Coastguard Worker                     OneFrame() ? 1 : testParams.iterationsPerStep,
803*8975f5c5SAndroid Build Coastguard Worker                     units),
804*8975f5c5SAndroid Build Coastguard Worker       mTestParams(testParams),
805*8975f5c5SAndroid Build Coastguard Worker       mIsTimestampQueryAvailable(false),
806*8975f5c5SAndroid Build Coastguard Worker       mGLWindow(nullptr),
807*8975f5c5SAndroid Build Coastguard Worker       mOSWindow(nullptr),
808*8975f5c5SAndroid Build Coastguard Worker       mSwapEnabled(true)
809*8975f5c5SAndroid Build Coastguard Worker {
810*8975f5c5SAndroid Build Coastguard Worker     // Force fast tests to make sure our slowest bots don't time out.
811*8975f5c5SAndroid Build Coastguard Worker     if (OneFrame())
812*8975f5c5SAndroid Build Coastguard Worker     {
813*8975f5c5SAndroid Build Coastguard Worker         const_cast<RenderTestParams &>(testParams).iterationsPerStep = 1;
814*8975f5c5SAndroid Build Coastguard Worker     }
815*8975f5c5SAndroid Build Coastguard Worker 
816*8975f5c5SAndroid Build Coastguard Worker     // Try to ensure we don't trigger allocation during execution.
817*8975f5c5SAndroid Build Coastguard Worker     mTraceEventBuffer.reserve(kInitialTraceEventBufferSize);
818*8975f5c5SAndroid Build Coastguard Worker 
819*8975f5c5SAndroid Build Coastguard Worker     switch (testParams.driver)
820*8975f5c5SAndroid Build Coastguard Worker     {
821*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::AngleEGL:
822*8975f5c5SAndroid Build Coastguard Worker             mGLWindow = EGLWindow::New(testParams.majorVersion, testParams.minorVersion);
823*8975f5c5SAndroid Build Coastguard Worker             mEntryPointsLib.reset(OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, SearchType::ModuleDir));
824*8975f5c5SAndroid Build Coastguard Worker             break;
825*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::AngleVulkanSecondariesEGL:
826*8975f5c5SAndroid Build Coastguard Worker             mGLWindow = EGLWindow::New(testParams.majorVersion, testParams.minorVersion);
827*8975f5c5SAndroid Build Coastguard Worker             mEntryPointsLib.reset(OpenSharedLibrary(ANGLE_VULKAN_SECONDARIES_EGL_LIBRARY_NAME,
828*8975f5c5SAndroid Build Coastguard Worker                                                     SearchType::ModuleDir));
829*8975f5c5SAndroid Build Coastguard Worker             break;
830*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::SystemEGL:
831*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_UTIL_LOADER) && !defined(ANGLE_PLATFORM_WINDOWS)
832*8975f5c5SAndroid Build Coastguard Worker             mGLWindow = EGLWindow::New(testParams.majorVersion, testParams.minorVersion);
833*8975f5c5SAndroid Build Coastguard Worker             mEntryPointsLib.reset(OpenSharedLibraryWithExtension(
834*8975f5c5SAndroid Build Coastguard Worker                 GetNativeEGLLibraryNameWithExtension(), SearchType::SystemDir));
835*8975f5c5SAndroid Build Coastguard Worker #else
836*8975f5c5SAndroid Build Coastguard Worker             skipTest("Not implemented.");
837*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_USE_UTIL_LOADER) && !defined(ANGLE_PLATFORM_WINDOWS)
838*8975f5c5SAndroid Build Coastguard Worker             break;
839*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::SystemWGL:
840*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
841*8975f5c5SAndroid Build Coastguard Worker             mGLWindow = WGLWindow::New(testParams.majorVersion, testParams.minorVersion);
842*8975f5c5SAndroid Build Coastguard Worker             mEntryPointsLib.reset(OpenSharedLibrary("opengl32", SearchType::SystemDir));
843*8975f5c5SAndroid Build Coastguard Worker #else
844*8975f5c5SAndroid Build Coastguard Worker             skipTest("WGL driver not available.");
845*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
846*8975f5c5SAndroid Build Coastguard Worker             break;
847*8975f5c5SAndroid Build Coastguard Worker         case GLESDriverType::ZinkEGL:
848*8975f5c5SAndroid Build Coastguard Worker             mGLWindow = EGLWindow::New(testParams.majorVersion, testParams.minorVersion);
849*8975f5c5SAndroid Build Coastguard Worker             mEntryPointsLib.reset(
850*8975f5c5SAndroid Build Coastguard Worker                 OpenSharedLibrary(ANGLE_MESA_EGL_LIBRARY_NAME, SearchType::ModuleDir));
851*8975f5c5SAndroid Build Coastguard Worker             break;
852*8975f5c5SAndroid Build Coastguard Worker         default:
853*8975f5c5SAndroid Build Coastguard Worker             skipTest("Error in switch.");
854*8975f5c5SAndroid Build Coastguard Worker             break;
855*8975f5c5SAndroid Build Coastguard Worker     }
856*8975f5c5SAndroid Build Coastguard Worker }
857*8975f5c5SAndroid Build Coastguard Worker 
~ANGLERenderTest()858*8975f5c5SAndroid Build Coastguard Worker ANGLERenderTest::~ANGLERenderTest()
859*8975f5c5SAndroid Build Coastguard Worker {
860*8975f5c5SAndroid Build Coastguard Worker     OSWindow::Delete(&mOSWindow);
861*8975f5c5SAndroid Build Coastguard Worker     GLWindowBase::Delete(&mGLWindow);
862*8975f5c5SAndroid Build Coastguard Worker }
863*8975f5c5SAndroid Build Coastguard Worker 
addExtensionPrerequisite(std::string extensionName)864*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::addExtensionPrerequisite(std::string extensionName)
865*8975f5c5SAndroid Build Coastguard Worker {
866*8975f5c5SAndroid Build Coastguard Worker     mExtensionPrerequisites.push_back(extensionName);
867*8975f5c5SAndroid Build Coastguard Worker }
868*8975f5c5SAndroid Build Coastguard Worker 
addIntegerPrerequisite(GLenum target,int min)869*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::addIntegerPrerequisite(GLenum target, int min)
870*8975f5c5SAndroid Build Coastguard Worker {
871*8975f5c5SAndroid Build Coastguard Worker     mIntegerPrerequisites.push_back({target, min});
872*8975f5c5SAndroid Build Coastguard Worker }
873*8975f5c5SAndroid Build Coastguard Worker 
SetUp()874*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::SetUp()
875*8975f5c5SAndroid Build Coastguard Worker {
876*8975f5c5SAndroid Build Coastguard Worker     if (mSkipTest)
877*8975f5c5SAndroid Build Coastguard Worker     {
878*8975f5c5SAndroid Build Coastguard Worker         return;
879*8975f5c5SAndroid Build Coastguard Worker     }
880*8975f5c5SAndroid Build Coastguard Worker 
881*8975f5c5SAndroid Build Coastguard Worker     // Set a consistent CPU core affinity and high priority.
882*8975f5c5SAndroid Build Coastguard Worker     StabilizeCPUForBenchmarking();
883*8975f5c5SAndroid Build Coastguard Worker 
884*8975f5c5SAndroid Build Coastguard Worker     mOSWindow = OSWindow::New();
885*8975f5c5SAndroid Build Coastguard Worker 
886*8975f5c5SAndroid Build Coastguard Worker     if (!mGLWindow)
887*8975f5c5SAndroid Build Coastguard Worker     {
888*8975f5c5SAndroid Build Coastguard Worker         skipTest("!mGLWindow");
889*8975f5c5SAndroid Build Coastguard Worker         return;
890*8975f5c5SAndroid Build Coastguard Worker     }
891*8975f5c5SAndroid Build Coastguard Worker 
892*8975f5c5SAndroid Build Coastguard Worker     mPlatformMethods.logError                    = CustomLogError;
893*8975f5c5SAndroid Build Coastguard Worker     mPlatformMethods.logWarning                  = EmptyPlatformMethod;
894*8975f5c5SAndroid Build Coastguard Worker     mPlatformMethods.logInfo                     = EmptyPlatformMethod;
895*8975f5c5SAndroid Build Coastguard Worker     mPlatformMethods.addTraceEvent               = AddPerfTraceEvent;
896*8975f5c5SAndroid Build Coastguard Worker     mPlatformMethods.getTraceCategoryEnabledFlag = GetPerfTraceCategoryEnabled;
897*8975f5c5SAndroid Build Coastguard Worker     mPlatformMethods.updateTraceEventDuration    = UpdateTraceEventDuration;
898*8975f5c5SAndroid Build Coastguard Worker     mPlatformMethods.monotonicallyIncreasingTime = MonotonicallyIncreasingTime;
899*8975f5c5SAndroid Build Coastguard Worker     mPlatformMethods.context                     = this;
900*8975f5c5SAndroid Build Coastguard Worker 
901*8975f5c5SAndroid Build Coastguard Worker     if (!mOSWindow->initialize(mName, mTestParams.windowWidth, mTestParams.windowHeight))
902*8975f5c5SAndroid Build Coastguard Worker     {
903*8975f5c5SAndroid Build Coastguard Worker         failTest("Failed initializing OSWindow");
904*8975f5c5SAndroid Build Coastguard Worker         return;
905*8975f5c5SAndroid Build Coastguard Worker     }
906*8975f5c5SAndroid Build Coastguard Worker 
907*8975f5c5SAndroid Build Coastguard Worker     // Override platform method parameter.
908*8975f5c5SAndroid Build Coastguard Worker     EGLPlatformParameters withMethods = mTestParams.eglParameters;
909*8975f5c5SAndroid Build Coastguard Worker     withMethods.platformMethods       = &mPlatformMethods;
910*8975f5c5SAndroid Build Coastguard Worker 
911*8975f5c5SAndroid Build Coastguard Worker     // Request a common framebuffer config
912*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.redBits     = 8;
913*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.greenBits   = 8;
914*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.blueBits    = 8;
915*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.alphaBits   = 8;
916*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.depthBits   = 24;
917*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.stencilBits = 8;
918*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.colorSpace  = mTestParams.colorSpace;
919*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.multisample = mTestParams.multisample;
920*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.samples     = mTestParams.samples;
921*8975f5c5SAndroid Build Coastguard Worker     if (mTestParams.surfaceType != SurfaceType::WindowWithVSync)
922*8975f5c5SAndroid Build Coastguard Worker     {
923*8975f5c5SAndroid Build Coastguard Worker         mConfigParams.swapInterval = 0;
924*8975f5c5SAndroid Build Coastguard Worker     }
925*8975f5c5SAndroid Build Coastguard Worker 
926*8975f5c5SAndroid Build Coastguard Worker     if (gPrintExtensionsToFile != nullptr || gRequestedExtensions != nullptr)
927*8975f5c5SAndroid Build Coastguard Worker     {
928*8975f5c5SAndroid Build Coastguard Worker         mConfigParams.extensionsEnabled = false;
929*8975f5c5SAndroid Build Coastguard Worker     }
930*8975f5c5SAndroid Build Coastguard Worker 
931*8975f5c5SAndroid Build Coastguard Worker     GLWindowResult res = mGLWindow->initializeGLWithResult(
932*8975f5c5SAndroid Build Coastguard Worker         mOSWindow, mEntryPointsLib.get(), mTestParams.driver, withMethods, mConfigParams);
933*8975f5c5SAndroid Build Coastguard Worker     switch (res)
934*8975f5c5SAndroid Build Coastguard Worker     {
935*8975f5c5SAndroid Build Coastguard Worker         case GLWindowResult::NoColorspaceSupport:
936*8975f5c5SAndroid Build Coastguard Worker             skipTest("Missing support for color spaces.");
937*8975f5c5SAndroid Build Coastguard Worker             return;
938*8975f5c5SAndroid Build Coastguard Worker         case GLWindowResult::Error:
939*8975f5c5SAndroid Build Coastguard Worker             failTest("Failed initializing GL Window");
940*8975f5c5SAndroid Build Coastguard Worker             return;
941*8975f5c5SAndroid Build Coastguard Worker         default:
942*8975f5c5SAndroid Build Coastguard Worker             break;
943*8975f5c5SAndroid Build Coastguard Worker     }
944*8975f5c5SAndroid Build Coastguard Worker 
945*8975f5c5SAndroid Build Coastguard Worker     if (gPrintExtensionsToFile)
946*8975f5c5SAndroid Build Coastguard Worker     {
947*8975f5c5SAndroid Build Coastguard Worker         std::ofstream fout(gPrintExtensionsToFile);
948*8975f5c5SAndroid Build Coastguard Worker         if (fout.is_open())
949*8975f5c5SAndroid Build Coastguard Worker         {
950*8975f5c5SAndroid Build Coastguard Worker             int numExtensions = 0;
951*8975f5c5SAndroid Build Coastguard Worker             glGetIntegerv(GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE, &numExtensions);
952*8975f5c5SAndroid Build Coastguard Worker             for (int ext = 0; ext < numExtensions; ext++)
953*8975f5c5SAndroid Build Coastguard Worker             {
954*8975f5c5SAndroid Build Coastguard Worker                 fout << glGetStringi(GL_REQUESTABLE_EXTENSIONS_ANGLE, ext) << std::endl;
955*8975f5c5SAndroid Build Coastguard Worker             }
956*8975f5c5SAndroid Build Coastguard Worker             fout.close();
957*8975f5c5SAndroid Build Coastguard Worker             std::stringstream statusString;
958*8975f5c5SAndroid Build Coastguard Worker             statusString << "Wrote out to file: " << gPrintExtensionsToFile;
959*8975f5c5SAndroid Build Coastguard Worker             skipTest(statusString.str());
960*8975f5c5SAndroid Build Coastguard Worker         }
961*8975f5c5SAndroid Build Coastguard Worker         else
962*8975f5c5SAndroid Build Coastguard Worker         {
963*8975f5c5SAndroid Build Coastguard Worker             std::stringstream failStr;
964*8975f5c5SAndroid Build Coastguard Worker             failStr << "Failed to open file: " << gPrintExtensionsToFile;
965*8975f5c5SAndroid Build Coastguard Worker             failTest(failStr.str());
966*8975f5c5SAndroid Build Coastguard Worker         }
967*8975f5c5SAndroid Build Coastguard Worker         return;
968*8975f5c5SAndroid Build Coastguard Worker     }
969*8975f5c5SAndroid Build Coastguard Worker 
970*8975f5c5SAndroid Build Coastguard Worker     if (gRequestedExtensions != nullptr)
971*8975f5c5SAndroid Build Coastguard Worker     {
972*8975f5c5SAndroid Build Coastguard Worker         std::istringstream ss{gRequestedExtensions};
973*8975f5c5SAndroid Build Coastguard Worker         std::string ext;
974*8975f5c5SAndroid Build Coastguard Worker         while (std::getline(ss, ext, ' '))
975*8975f5c5SAndroid Build Coastguard Worker         {
976*8975f5c5SAndroid Build Coastguard Worker             glRequestExtensionANGLE(ext.c_str());
977*8975f5c5SAndroid Build Coastguard Worker         }
978*8975f5c5SAndroid Build Coastguard Worker     }
979*8975f5c5SAndroid Build Coastguard Worker 
980*8975f5c5SAndroid Build Coastguard Worker     // Disable vsync (if not done by the window init).
981*8975f5c5SAndroid Build Coastguard Worker     if (mTestParams.surfaceType != SurfaceType::WindowWithVSync)
982*8975f5c5SAndroid Build Coastguard Worker     {
983*8975f5c5SAndroid Build Coastguard Worker         if (!mGLWindow->setSwapInterval(0))
984*8975f5c5SAndroid Build Coastguard Worker         {
985*8975f5c5SAndroid Build Coastguard Worker             failTest("Failed setting swap interval");
986*8975f5c5SAndroid Build Coastguard Worker             return;
987*8975f5c5SAndroid Build Coastguard Worker         }
988*8975f5c5SAndroid Build Coastguard Worker     }
989*8975f5c5SAndroid Build Coastguard Worker 
990*8975f5c5SAndroid Build Coastguard Worker     if (mTestParams.trackGpuTime)
991*8975f5c5SAndroid Build Coastguard Worker     {
992*8975f5c5SAndroid Build Coastguard Worker         mIsTimestampQueryAvailable = EnsureGLExtensionEnabled("GL_EXT_disjoint_timer_query");
993*8975f5c5SAndroid Build Coastguard Worker     }
994*8975f5c5SAndroid Build Coastguard Worker 
995*8975f5c5SAndroid Build Coastguard Worker     skipTestIfMissingExtensionPrerequisites();
996*8975f5c5SAndroid Build Coastguard Worker     skipTestIfFailsIntegerPrerequisite();
997*8975f5c5SAndroid Build Coastguard Worker 
998*8975f5c5SAndroid Build Coastguard Worker     if (mSkipTest)
999*8975f5c5SAndroid Build Coastguard Worker     {
1000*8975f5c5SAndroid Build Coastguard Worker         GTEST_SKIP() << mSkipTestReason;
1001*8975f5c5SAndroid Build Coastguard Worker         // GTEST_SKIP returns.
1002*8975f5c5SAndroid Build Coastguard Worker     }
1003*8975f5c5SAndroid Build Coastguard Worker 
1004*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_ASSERTS)
1005*8975f5c5SAndroid Build Coastguard Worker     if (IsGLExtensionEnabled("GL_KHR_debug") && mEnableDebugCallback)
1006*8975f5c5SAndroid Build Coastguard Worker     {
1007*8975f5c5SAndroid Build Coastguard Worker         EnableDebugCallback(&PerfTestDebugCallback, this);
1008*8975f5c5SAndroid Build Coastguard Worker     }
1009*8975f5c5SAndroid Build Coastguard Worker #endif
1010*8975f5c5SAndroid Build Coastguard Worker 
1011*8975f5c5SAndroid Build Coastguard Worker     initializeBenchmark();
1012*8975f5c5SAndroid Build Coastguard Worker 
1013*8975f5c5SAndroid Build Coastguard Worker     if (mSkipTest)
1014*8975f5c5SAndroid Build Coastguard Worker     {
1015*8975f5c5SAndroid Build Coastguard Worker         GTEST_SKIP() << mSkipTestReason;
1016*8975f5c5SAndroid Build Coastguard Worker         // GTEST_SKIP returns.
1017*8975f5c5SAndroid Build Coastguard Worker     }
1018*8975f5c5SAndroid Build Coastguard Worker 
1019*8975f5c5SAndroid Build Coastguard Worker     if (mTestParams.iterationsPerStep == 0)
1020*8975f5c5SAndroid Build Coastguard Worker     {
1021*8975f5c5SAndroid Build Coastguard Worker         failTest("Please initialize 'iterationsPerStep'.");
1022*8975f5c5SAndroid Build Coastguard Worker         return;
1023*8975f5c5SAndroid Build Coastguard Worker     }
1024*8975f5c5SAndroid Build Coastguard Worker 
1025*8975f5c5SAndroid Build Coastguard Worker     if (gVerboseLogging)
1026*8975f5c5SAndroid Build Coastguard Worker     {
1027*8975f5c5SAndroid Build Coastguard Worker         printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
1028*8975f5c5SAndroid Build Coastguard Worker         printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
1029*8975f5c5SAndroid Build Coastguard Worker     }
1030*8975f5c5SAndroid Build Coastguard Worker 
1031*8975f5c5SAndroid Build Coastguard Worker     mTestTrialResults.reserve(gTestTrials);
1032*8975f5c5SAndroid Build Coastguard Worker 
1033*8975f5c5SAndroid Build Coastguard Worker     // Runs warmup if enabled
1034*8975f5c5SAndroid Build Coastguard Worker     ANGLEPerfTest::SetUp();
1035*8975f5c5SAndroid Build Coastguard Worker 
1036*8975f5c5SAndroid Build Coastguard Worker     initPerfCounters();
1037*8975f5c5SAndroid Build Coastguard Worker }
1038*8975f5c5SAndroid Build Coastguard Worker 
TearDown()1039*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::TearDown()
1040*8975f5c5SAndroid Build Coastguard Worker {
1041*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mTimestampQueries.empty());
1042*8975f5c5SAndroid Build Coastguard Worker 
1043*8975f5c5SAndroid Build Coastguard Worker     if (!mPerfCounterInfo.empty())
1044*8975f5c5SAndroid Build Coastguard Worker     {
1045*8975f5c5SAndroid Build Coastguard Worker         glDeletePerfMonitorsAMD(1, &mPerfMonitor);
1046*8975f5c5SAndroid Build Coastguard Worker         mPerfMonitor = 0;
1047*8975f5c5SAndroid Build Coastguard Worker     }
1048*8975f5c5SAndroid Build Coastguard Worker 
1049*8975f5c5SAndroid Build Coastguard Worker     if (!mSkipTest)
1050*8975f5c5SAndroid Build Coastguard Worker     {
1051*8975f5c5SAndroid Build Coastguard Worker         destroyBenchmark();
1052*8975f5c5SAndroid Build Coastguard Worker     }
1053*8975f5c5SAndroid Build Coastguard Worker 
1054*8975f5c5SAndroid Build Coastguard Worker     if (mGLWindow)
1055*8975f5c5SAndroid Build Coastguard Worker     {
1056*8975f5c5SAndroid Build Coastguard Worker         mGLWindow->destroyGL();
1057*8975f5c5SAndroid Build Coastguard Worker         mGLWindow = nullptr;
1058*8975f5c5SAndroid Build Coastguard Worker     }
1059*8975f5c5SAndroid Build Coastguard Worker 
1060*8975f5c5SAndroid Build Coastguard Worker     if (mOSWindow)
1061*8975f5c5SAndroid Build Coastguard Worker     {
1062*8975f5c5SAndroid Build Coastguard Worker         mOSWindow->destroy();
1063*8975f5c5SAndroid Build Coastguard Worker         mOSWindow = nullptr;
1064*8975f5c5SAndroid Build Coastguard Worker     }
1065*8975f5c5SAndroid Build Coastguard Worker 
1066*8975f5c5SAndroid Build Coastguard Worker     // Dump trace events to json file.
1067*8975f5c5SAndroid Build Coastguard Worker     if (gEnableTrace)
1068*8975f5c5SAndroid Build Coastguard Worker     {
1069*8975f5c5SAndroid Build Coastguard Worker         DumpTraceEventsToJSONFile(mTraceEventBuffer, gTraceFile);
1070*8975f5c5SAndroid Build Coastguard Worker     }
1071*8975f5c5SAndroid Build Coastguard Worker 
1072*8975f5c5SAndroid Build Coastguard Worker     ANGLEPerfTest::TearDown();
1073*8975f5c5SAndroid Build Coastguard Worker }
1074*8975f5c5SAndroid Build Coastguard Worker 
initPerfCounters()1075*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::initPerfCounters()
1076*8975f5c5SAndroid Build Coastguard Worker {
1077*8975f5c5SAndroid Build Coastguard Worker     if (!gPerfCounters)
1078*8975f5c5SAndroid Build Coastguard Worker     {
1079*8975f5c5SAndroid Build Coastguard Worker         return;
1080*8975f5c5SAndroid Build Coastguard Worker     }
1081*8975f5c5SAndroid Build Coastguard Worker 
1082*8975f5c5SAndroid Build Coastguard Worker     if (!IsGLExtensionEnabled(kPerfMonitorExtensionName))
1083*8975f5c5SAndroid Build Coastguard Worker     {
1084*8975f5c5SAndroid Build Coastguard Worker         fprintf(stderr, "Cannot report perf metrics because %s is not available.\n",
1085*8975f5c5SAndroid Build Coastguard Worker                 kPerfMonitorExtensionName);
1086*8975f5c5SAndroid Build Coastguard Worker         return;
1087*8975f5c5SAndroid Build Coastguard Worker     }
1088*8975f5c5SAndroid Build Coastguard Worker 
1089*8975f5c5SAndroid Build Coastguard Worker     CounterNameToIndexMap indexMap = BuildCounterNameToIndexMap();
1090*8975f5c5SAndroid Build Coastguard Worker 
1091*8975f5c5SAndroid Build Coastguard Worker     std::vector<std::string> counters =
1092*8975f5c5SAndroid Build Coastguard Worker         angle::SplitString(gPerfCounters, ":", angle::WhitespaceHandling::TRIM_WHITESPACE,
1093*8975f5c5SAndroid Build Coastguard Worker                            angle::SplitResult::SPLIT_WANT_NONEMPTY);
1094*8975f5c5SAndroid Build Coastguard Worker     for (const std::string &counter : counters)
1095*8975f5c5SAndroid Build Coastguard Worker     {
1096*8975f5c5SAndroid Build Coastguard Worker         bool found = false;
1097*8975f5c5SAndroid Build Coastguard Worker 
1098*8975f5c5SAndroid Build Coastguard Worker         for (const auto &indexMapIter : indexMap)
1099*8975f5c5SAndroid Build Coastguard Worker         {
1100*8975f5c5SAndroid Build Coastguard Worker             const std::string &indexMapName = indexMapIter.first;
1101*8975f5c5SAndroid Build Coastguard Worker             if (NamesMatchWithWildcard(counter.c_str(), indexMapName.c_str()))
1102*8975f5c5SAndroid Build Coastguard Worker             {
1103*8975f5c5SAndroid Build Coastguard Worker                 {
1104*8975f5c5SAndroid Build Coastguard Worker                     std::stringstream medianStr;
1105*8975f5c5SAndroid Build Coastguard Worker                     medianStr << '.' << indexMapName << "_median";
1106*8975f5c5SAndroid Build Coastguard Worker                     std::string medianName = medianStr.str();
1107*8975f5c5SAndroid Build Coastguard Worker                     mReporter->RegisterImportantMetric(medianName, "count");
1108*8975f5c5SAndroid Build Coastguard Worker                 }
1109*8975f5c5SAndroid Build Coastguard Worker 
1110*8975f5c5SAndroid Build Coastguard Worker                 {
1111*8975f5c5SAndroid Build Coastguard Worker                     std::stringstream maxStr;
1112*8975f5c5SAndroid Build Coastguard Worker                     maxStr << '.' << indexMapName << "_max";
1113*8975f5c5SAndroid Build Coastguard Worker                     std::string maxName = maxStr.str();
1114*8975f5c5SAndroid Build Coastguard Worker                     mReporter->RegisterImportantMetric(maxName, "count");
1115*8975f5c5SAndroid Build Coastguard Worker                 }
1116*8975f5c5SAndroid Build Coastguard Worker 
1117*8975f5c5SAndroid Build Coastguard Worker                 {
1118*8975f5c5SAndroid Build Coastguard Worker                     std::stringstream sumStr;
1119*8975f5c5SAndroid Build Coastguard Worker                     sumStr << '.' << indexMapName << "_sum";
1120*8975f5c5SAndroid Build Coastguard Worker                     std::string sumName = sumStr.str();
1121*8975f5c5SAndroid Build Coastguard Worker                     mReporter->RegisterImportantMetric(sumName, "count");
1122*8975f5c5SAndroid Build Coastguard Worker                 }
1123*8975f5c5SAndroid Build Coastguard Worker 
1124*8975f5c5SAndroid Build Coastguard Worker                 GLuint index            = indexMapIter.second;
1125*8975f5c5SAndroid Build Coastguard Worker                 mPerfCounterInfo[index] = {indexMapName, {}};
1126*8975f5c5SAndroid Build Coastguard Worker 
1127*8975f5c5SAndroid Build Coastguard Worker                 found = true;
1128*8975f5c5SAndroid Build Coastguard Worker             }
1129*8975f5c5SAndroid Build Coastguard Worker         }
1130*8975f5c5SAndroid Build Coastguard Worker 
1131*8975f5c5SAndroid Build Coastguard Worker         if (!found)
1132*8975f5c5SAndroid Build Coastguard Worker         {
1133*8975f5c5SAndroid Build Coastguard Worker             fprintf(stderr, "'%s' does not match any available perf counters.\n", counter.c_str());
1134*8975f5c5SAndroid Build Coastguard Worker         }
1135*8975f5c5SAndroid Build Coastguard Worker     }
1136*8975f5c5SAndroid Build Coastguard Worker 
1137*8975f5c5SAndroid Build Coastguard Worker     if (!mPerfCounterInfo.empty())
1138*8975f5c5SAndroid Build Coastguard Worker     {
1139*8975f5c5SAndroid Build Coastguard Worker         glGenPerfMonitorsAMD(1, &mPerfMonitor);
1140*8975f5c5SAndroid Build Coastguard Worker         // Note: technically, glSelectPerfMonitorCountersAMD should be used to select the counters,
1141*8975f5c5SAndroid Build Coastguard Worker         // but currently ANGLE always captures all counters.
1142*8975f5c5SAndroid Build Coastguard Worker     }
1143*8975f5c5SAndroid Build Coastguard Worker }
1144*8975f5c5SAndroid Build Coastguard Worker 
updatePerfCounters()1145*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::updatePerfCounters()
1146*8975f5c5SAndroid Build Coastguard Worker {
1147*8975f5c5SAndroid Build Coastguard Worker     if (mPerfCounterInfo.empty())
1148*8975f5c5SAndroid Build Coastguard Worker     {
1149*8975f5c5SAndroid Build Coastguard Worker         return;
1150*8975f5c5SAndroid Build Coastguard Worker     }
1151*8975f5c5SAndroid Build Coastguard Worker 
1152*8975f5c5SAndroid Build Coastguard Worker     std::vector<PerfMonitorTriplet> perfData = GetPerfMonitorTriplets();
1153*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!perfData.empty());
1154*8975f5c5SAndroid Build Coastguard Worker 
1155*8975f5c5SAndroid Build Coastguard Worker     for (auto &iter : mPerfCounterInfo)
1156*8975f5c5SAndroid Build Coastguard Worker     {
1157*8975f5c5SAndroid Build Coastguard Worker         uint32_t counter               = iter.first;
1158*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLuint64> &samples = iter.second.samples;
1159*8975f5c5SAndroid Build Coastguard Worker         samples.push_back(perfData[counter].value);
1160*8975f5c5SAndroid Build Coastguard Worker     }
1161*8975f5c5SAndroid Build Coastguard Worker }
1162*8975f5c5SAndroid Build Coastguard Worker 
beginInternalTraceEvent(const char * name)1163*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::beginInternalTraceEvent(const char *name)
1164*8975f5c5SAndroid Build Coastguard Worker {
1165*8975f5c5SAndroid Build Coastguard Worker     if (gEnableTrace)
1166*8975f5c5SAndroid Build Coastguard Worker     {
1167*8975f5c5SAndroid Build Coastguard Worker         mTraceEventBuffer.emplace_back(TRACE_EVENT_PHASE_BEGIN, gTraceCategories[0].name, name,
1168*8975f5c5SAndroid Build Coastguard Worker                                        MonotonicallyIncreasingTime(&mPlatformMethods),
1169*8975f5c5SAndroid Build Coastguard Worker                                        getCurrentThreadSerial());
1170*8975f5c5SAndroid Build Coastguard Worker     }
1171*8975f5c5SAndroid Build Coastguard Worker }
1172*8975f5c5SAndroid Build Coastguard Worker 
endInternalTraceEvent(const char * name)1173*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::endInternalTraceEvent(const char *name)
1174*8975f5c5SAndroid Build Coastguard Worker {
1175*8975f5c5SAndroid Build Coastguard Worker     if (gEnableTrace)
1176*8975f5c5SAndroid Build Coastguard Worker     {
1177*8975f5c5SAndroid Build Coastguard Worker         mTraceEventBuffer.emplace_back(TRACE_EVENT_PHASE_END, gTraceCategories[0].name, name,
1178*8975f5c5SAndroid Build Coastguard Worker                                        MonotonicallyIncreasingTime(&mPlatformMethods),
1179*8975f5c5SAndroid Build Coastguard Worker                                        getCurrentThreadSerial());
1180*8975f5c5SAndroid Build Coastguard Worker     }
1181*8975f5c5SAndroid Build Coastguard Worker }
1182*8975f5c5SAndroid Build Coastguard Worker 
beginGLTraceEvent(const char * name,double hostTimeSec)1183*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::beginGLTraceEvent(const char *name, double hostTimeSec)
1184*8975f5c5SAndroid Build Coastguard Worker {
1185*8975f5c5SAndroid Build Coastguard Worker     if (gEnableTrace)
1186*8975f5c5SAndroid Build Coastguard Worker     {
1187*8975f5c5SAndroid Build Coastguard Worker         mTraceEventBuffer.emplace_back(TRACE_EVENT_PHASE_BEGIN, gTraceCategories[1].name, name,
1188*8975f5c5SAndroid Build Coastguard Worker                                        hostTimeSec, getCurrentThreadSerial());
1189*8975f5c5SAndroid Build Coastguard Worker     }
1190*8975f5c5SAndroid Build Coastguard Worker }
1191*8975f5c5SAndroid Build Coastguard Worker 
endGLTraceEvent(const char * name,double hostTimeSec)1192*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::endGLTraceEvent(const char *name, double hostTimeSec)
1193*8975f5c5SAndroid Build Coastguard Worker {
1194*8975f5c5SAndroid Build Coastguard Worker     if (gEnableTrace)
1195*8975f5c5SAndroid Build Coastguard Worker     {
1196*8975f5c5SAndroid Build Coastguard Worker         mTraceEventBuffer.emplace_back(TRACE_EVENT_PHASE_END, gTraceCategories[1].name, name,
1197*8975f5c5SAndroid Build Coastguard Worker                                        hostTimeSec, getCurrentThreadSerial());
1198*8975f5c5SAndroid Build Coastguard Worker     }
1199*8975f5c5SAndroid Build Coastguard Worker }
1200*8975f5c5SAndroid Build Coastguard Worker 
step()1201*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::step()
1202*8975f5c5SAndroid Build Coastguard Worker {
1203*8975f5c5SAndroid Build Coastguard Worker     beginInternalTraceEvent("step");
1204*8975f5c5SAndroid Build Coastguard Worker 
1205*8975f5c5SAndroid Build Coastguard Worker     // Clear events that the application did not process from this frame
1206*8975f5c5SAndroid Build Coastguard Worker     Event event;
1207*8975f5c5SAndroid Build Coastguard Worker     bool closed = false;
1208*8975f5c5SAndroid Build Coastguard Worker     while (popEvent(&event))
1209*8975f5c5SAndroid Build Coastguard Worker     {
1210*8975f5c5SAndroid Build Coastguard Worker         // If the application did not catch a close event, close now
1211*8975f5c5SAndroid Build Coastguard Worker         if (event.Type == Event::EVENT_CLOSED)
1212*8975f5c5SAndroid Build Coastguard Worker         {
1213*8975f5c5SAndroid Build Coastguard Worker             closed = true;
1214*8975f5c5SAndroid Build Coastguard Worker         }
1215*8975f5c5SAndroid Build Coastguard Worker     }
1216*8975f5c5SAndroid Build Coastguard Worker 
1217*8975f5c5SAndroid Build Coastguard Worker     if (closed)
1218*8975f5c5SAndroid Build Coastguard Worker     {
1219*8975f5c5SAndroid Build Coastguard Worker         abortTest();
1220*8975f5c5SAndroid Build Coastguard Worker     }
1221*8975f5c5SAndroid Build Coastguard Worker     else
1222*8975f5c5SAndroid Build Coastguard Worker     {
1223*8975f5c5SAndroid Build Coastguard Worker         drawBenchmark();
1224*8975f5c5SAndroid Build Coastguard Worker 
1225*8975f5c5SAndroid Build Coastguard Worker         // Swap is needed so that the GPU driver will occasionally flush its
1226*8975f5c5SAndroid Build Coastguard Worker         // internal command queue to the GPU. This is enabled for null back-end
1227*8975f5c5SAndroid Build Coastguard Worker         // devices because some back-ends (e.g. Vulkan) also accumulate internal
1228*8975f5c5SAndroid Build Coastguard Worker         // command queues.
1229*8975f5c5SAndroid Build Coastguard Worker         if (mSwapEnabled)
1230*8975f5c5SAndroid Build Coastguard Worker         {
1231*8975f5c5SAndroid Build Coastguard Worker             updatePerfCounters();
1232*8975f5c5SAndroid Build Coastguard Worker             mGLWindow->swap();
1233*8975f5c5SAndroid Build Coastguard Worker         }
1234*8975f5c5SAndroid Build Coastguard Worker         mOSWindow->messageLoop();
1235*8975f5c5SAndroid Build Coastguard Worker 
1236*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_ASSERTS)
1237*8975f5c5SAndroid Build Coastguard Worker         if (!gRetraceMode)
1238*8975f5c5SAndroid Build Coastguard Worker         {
1239*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
1240*8975f5c5SAndroid Build Coastguard Worker         }
1241*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_ENABLE_ASSERTS)
1242*8975f5c5SAndroid Build Coastguard Worker 
1243*8975f5c5SAndroid Build Coastguard Worker         // Sample system memory
1244*8975f5c5SAndroid Build Coastguard Worker         uint64_t processMemoryUsageKB = GetProcessMemoryUsageKB();
1245*8975f5c5SAndroid Build Coastguard Worker         if (processMemoryUsageKB)
1246*8975f5c5SAndroid Build Coastguard Worker         {
1247*8975f5c5SAndroid Build Coastguard Worker             mProcessMemoryUsageKBSamples.push_back(processMemoryUsageKB);
1248*8975f5c5SAndroid Build Coastguard Worker         }
1249*8975f5c5SAndroid Build Coastguard Worker     }
1250*8975f5c5SAndroid Build Coastguard Worker 
1251*8975f5c5SAndroid Build Coastguard Worker     endInternalTraceEvent("step");
1252*8975f5c5SAndroid Build Coastguard Worker }
1253*8975f5c5SAndroid Build Coastguard Worker 
startGpuTimer()1254*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::startGpuTimer()
1255*8975f5c5SAndroid Build Coastguard Worker {
1256*8975f5c5SAndroid Build Coastguard Worker     if (mTestParams.trackGpuTime && mIsTimestampQueryAvailable)
1257*8975f5c5SAndroid Build Coastguard Worker     {
1258*8975f5c5SAndroid Build Coastguard Worker         glGenQueriesEXT(1, &mCurrentTimestampBeginQuery);
1259*8975f5c5SAndroid Build Coastguard Worker         glQueryCounterEXT(mCurrentTimestampBeginQuery, GL_TIMESTAMP_EXT);
1260*8975f5c5SAndroid Build Coastguard Worker     }
1261*8975f5c5SAndroid Build Coastguard Worker }
1262*8975f5c5SAndroid Build Coastguard Worker 
stopGpuTimer()1263*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::stopGpuTimer()
1264*8975f5c5SAndroid Build Coastguard Worker {
1265*8975f5c5SAndroid Build Coastguard Worker     if (mTestParams.trackGpuTime && mIsTimestampQueryAvailable)
1266*8975f5c5SAndroid Build Coastguard Worker     {
1267*8975f5c5SAndroid Build Coastguard Worker         GLuint endQuery = 0;
1268*8975f5c5SAndroid Build Coastguard Worker         glGenQueriesEXT(1, &endQuery);
1269*8975f5c5SAndroid Build Coastguard Worker         glQueryCounterEXT(endQuery, GL_TIMESTAMP_EXT);
1270*8975f5c5SAndroid Build Coastguard Worker         mTimestampQueries.push({mCurrentTimestampBeginQuery, endQuery});
1271*8975f5c5SAndroid Build Coastguard Worker     }
1272*8975f5c5SAndroid Build Coastguard Worker }
1273*8975f5c5SAndroid Build Coastguard Worker 
computeGPUTime()1274*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::computeGPUTime()
1275*8975f5c5SAndroid Build Coastguard Worker {
1276*8975f5c5SAndroid Build Coastguard Worker     if (mTestParams.trackGpuTime && mIsTimestampQueryAvailable)
1277*8975f5c5SAndroid Build Coastguard Worker     {
1278*8975f5c5SAndroid Build Coastguard Worker         while (!mTimestampQueries.empty())
1279*8975f5c5SAndroid Build Coastguard Worker         {
1280*8975f5c5SAndroid Build Coastguard Worker             const TimestampSample &sample = mTimestampQueries.front();
1281*8975f5c5SAndroid Build Coastguard Worker             GLuint available              = GL_FALSE;
1282*8975f5c5SAndroid Build Coastguard Worker             glGetQueryObjectuivEXT(sample.endQuery, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
1283*8975f5c5SAndroid Build Coastguard Worker             if (available != GL_TRUE)
1284*8975f5c5SAndroid Build Coastguard Worker             {
1285*8975f5c5SAndroid Build Coastguard Worker                 // query is not completed yet, bail out
1286*8975f5c5SAndroid Build Coastguard Worker                 break;
1287*8975f5c5SAndroid Build Coastguard Worker             }
1288*8975f5c5SAndroid Build Coastguard Worker 
1289*8975f5c5SAndroid Build Coastguard Worker             // frame's begin query must also completed.
1290*8975f5c5SAndroid Build Coastguard Worker             glGetQueryObjectuivEXT(sample.beginQuery, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
1291*8975f5c5SAndroid Build Coastguard Worker             ASSERT(available == GL_TRUE);
1292*8975f5c5SAndroid Build Coastguard Worker 
1293*8975f5c5SAndroid Build Coastguard Worker             // Retrieve query result
1294*8975f5c5SAndroid Build Coastguard Worker             uint64_t beginGLTimeNs = 0;
1295*8975f5c5SAndroid Build Coastguard Worker             uint64_t endGLTimeNs   = 0;
1296*8975f5c5SAndroid Build Coastguard Worker             glGetQueryObjectui64vEXT(sample.beginQuery, GL_QUERY_RESULT_EXT, &beginGLTimeNs);
1297*8975f5c5SAndroid Build Coastguard Worker             glGetQueryObjectui64vEXT(sample.endQuery, GL_QUERY_RESULT_EXT, &endGLTimeNs);
1298*8975f5c5SAndroid Build Coastguard Worker             glDeleteQueriesEXT(1, &sample.beginQuery);
1299*8975f5c5SAndroid Build Coastguard Worker             glDeleteQueriesEXT(1, &sample.endQuery);
1300*8975f5c5SAndroid Build Coastguard Worker             mTimestampQueries.pop();
1301*8975f5c5SAndroid Build Coastguard Worker 
1302*8975f5c5SAndroid Build Coastguard Worker             // compute GPU time
1303*8975f5c5SAndroid Build Coastguard Worker             mGPUTimeNs += endGLTimeNs - beginGLTimeNs;
1304*8975f5c5SAndroid Build Coastguard Worker         }
1305*8975f5c5SAndroid Build Coastguard Worker     }
1306*8975f5c5SAndroid Build Coastguard Worker }
1307*8975f5c5SAndroid Build Coastguard Worker 
startTest()1308*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::startTest()
1309*8975f5c5SAndroid Build Coastguard Worker {
1310*8975f5c5SAndroid Build Coastguard Worker     if (!mPerfCounterInfo.empty())
1311*8975f5c5SAndroid Build Coastguard Worker     {
1312*8975f5c5SAndroid Build Coastguard Worker         glBeginPerfMonitorAMD(mPerfMonitor);
1313*8975f5c5SAndroid Build Coastguard Worker     }
1314*8975f5c5SAndroid Build Coastguard Worker }
1315*8975f5c5SAndroid Build Coastguard Worker 
finishTest()1316*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::finishTest()
1317*8975f5c5SAndroid Build Coastguard Worker {
1318*8975f5c5SAndroid Build Coastguard Worker     if (mTestParams.eglParameters.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE &&
1319*8975f5c5SAndroid Build Coastguard Worker         !gNoFinish && !gRetraceMode)
1320*8975f5c5SAndroid Build Coastguard Worker     {
1321*8975f5c5SAndroid Build Coastguard Worker         FinishAndCheckForContextLoss();
1322*8975f5c5SAndroid Build Coastguard Worker     }
1323*8975f5c5SAndroid Build Coastguard Worker 
1324*8975f5c5SAndroid Build Coastguard Worker     if (!mPerfCounterInfo.empty())
1325*8975f5c5SAndroid Build Coastguard Worker     {
1326*8975f5c5SAndroid Build Coastguard Worker         glEndPerfMonitorAMD(mPerfMonitor);
1327*8975f5c5SAndroid Build Coastguard Worker     }
1328*8975f5c5SAndroid Build Coastguard Worker }
1329*8975f5c5SAndroid Build Coastguard Worker 
popEvent(Event * event)1330*8975f5c5SAndroid Build Coastguard Worker bool ANGLERenderTest::popEvent(Event *event)
1331*8975f5c5SAndroid Build Coastguard Worker {
1332*8975f5c5SAndroid Build Coastguard Worker     return mOSWindow->popEvent(event);
1333*8975f5c5SAndroid Build Coastguard Worker }
1334*8975f5c5SAndroid Build Coastguard Worker 
getWindow()1335*8975f5c5SAndroid Build Coastguard Worker OSWindow *ANGLERenderTest::getWindow()
1336*8975f5c5SAndroid Build Coastguard Worker {
1337*8975f5c5SAndroid Build Coastguard Worker     return mOSWindow;
1338*8975f5c5SAndroid Build Coastguard Worker }
1339*8975f5c5SAndroid Build Coastguard Worker 
getGLWindow()1340*8975f5c5SAndroid Build Coastguard Worker GLWindowBase *ANGLERenderTest::getGLWindow()
1341*8975f5c5SAndroid Build Coastguard Worker {
1342*8975f5c5SAndroid Build Coastguard Worker     return mGLWindow;
1343*8975f5c5SAndroid Build Coastguard Worker }
1344*8975f5c5SAndroid Build Coastguard Worker 
skipTestIfMissingExtensionPrerequisites()1345*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::skipTestIfMissingExtensionPrerequisites()
1346*8975f5c5SAndroid Build Coastguard Worker {
1347*8975f5c5SAndroid Build Coastguard Worker     for (std::string extension : mExtensionPrerequisites)
1348*8975f5c5SAndroid Build Coastguard Worker     {
1349*8975f5c5SAndroid Build Coastguard Worker         if (!CheckExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
1350*8975f5c5SAndroid Build Coastguard Worker                                   extension))
1351*8975f5c5SAndroid Build Coastguard Worker         {
1352*8975f5c5SAndroid Build Coastguard Worker             skipTest(std::string("Test skipped due to missing extension: ") + extension);
1353*8975f5c5SAndroid Build Coastguard Worker             return;
1354*8975f5c5SAndroid Build Coastguard Worker         }
1355*8975f5c5SAndroid Build Coastguard Worker     }
1356*8975f5c5SAndroid Build Coastguard Worker }
1357*8975f5c5SAndroid Build Coastguard Worker 
skipTestIfFailsIntegerPrerequisite()1358*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::skipTestIfFailsIntegerPrerequisite()
1359*8975f5c5SAndroid Build Coastguard Worker {
1360*8975f5c5SAndroid Build Coastguard Worker     for (const auto [target, minRequired] : mIntegerPrerequisites)
1361*8975f5c5SAndroid Build Coastguard Worker     {
1362*8975f5c5SAndroid Build Coastguard Worker         GLint driverValue;
1363*8975f5c5SAndroid Build Coastguard Worker         glGetIntegerv(target, &driverValue);
1364*8975f5c5SAndroid Build Coastguard Worker         if (static_cast<int>(driverValue) < minRequired)
1365*8975f5c5SAndroid Build Coastguard Worker         {
1366*8975f5c5SAndroid Build Coastguard Worker             std::stringstream ss;
1367*8975f5c5SAndroid Build Coastguard Worker             ss << "Test skipped due to value (" << std::to_string(static_cast<int>(driverValue))
1368*8975f5c5SAndroid Build Coastguard Worker                << ") being less than the prerequisite minimum (" << std::to_string(minRequired)
1369*8975f5c5SAndroid Build Coastguard Worker                << ") for GL constant " << gl::GLenumToString(gl::GLESEnum::AllEnums, target);
1370*8975f5c5SAndroid Build Coastguard Worker             skipTest(ss.str());
1371*8975f5c5SAndroid Build Coastguard Worker         }
1372*8975f5c5SAndroid Build Coastguard Worker     }
1373*8975f5c5SAndroid Build Coastguard Worker }
1374*8975f5c5SAndroid Build Coastguard Worker 
setWebGLCompatibilityEnabled(bool webglCompatibility)1375*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::setWebGLCompatibilityEnabled(bool webglCompatibility)
1376*8975f5c5SAndroid Build Coastguard Worker {
1377*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.webGLCompatibility = webglCompatibility;
1378*8975f5c5SAndroid Build Coastguard Worker }
1379*8975f5c5SAndroid Build Coastguard Worker 
setRobustResourceInit(bool enabled)1380*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::setRobustResourceInit(bool enabled)
1381*8975f5c5SAndroid Build Coastguard Worker {
1382*8975f5c5SAndroid Build Coastguard Worker     mConfigParams.robustResourceInit = enabled;
1383*8975f5c5SAndroid Build Coastguard Worker }
1384*8975f5c5SAndroid Build Coastguard Worker 
getTraceEventBuffer()1385*8975f5c5SAndroid Build Coastguard Worker std::vector<TraceEvent> &ANGLERenderTest::getTraceEventBuffer()
1386*8975f5c5SAndroid Build Coastguard Worker {
1387*8975f5c5SAndroid Build Coastguard Worker     return mTraceEventBuffer;
1388*8975f5c5SAndroid Build Coastguard Worker }
1389*8975f5c5SAndroid Build Coastguard Worker 
onErrorMessage(const char * errorMessage)1390*8975f5c5SAndroid Build Coastguard Worker void ANGLERenderTest::onErrorMessage(const char *errorMessage)
1391*8975f5c5SAndroid Build Coastguard Worker {
1392*8975f5c5SAndroid Build Coastguard Worker     abortTest();
1393*8975f5c5SAndroid Build Coastguard Worker     std::ostringstream err;
1394*8975f5c5SAndroid Build Coastguard Worker     err << "Failing test because of unexpected error:\n" << errorMessage << "\n";
1395*8975f5c5SAndroid Build Coastguard Worker     failTest(err.str());
1396*8975f5c5SAndroid Build Coastguard Worker }
1397*8975f5c5SAndroid Build Coastguard Worker 
getCurrentThreadSerial()1398*8975f5c5SAndroid Build Coastguard Worker uint32_t ANGLERenderTest::getCurrentThreadSerial()
1399*8975f5c5SAndroid Build Coastguard Worker {
1400*8975f5c5SAndroid Build Coastguard Worker     uint64_t id = angle::GetCurrentThreadUniqueId();
1401*8975f5c5SAndroid Build Coastguard Worker 
1402*8975f5c5SAndroid Build Coastguard Worker     for (uint32_t serial = 0; serial < static_cast<uint32_t>(mThreadIDs.size()); ++serial)
1403*8975f5c5SAndroid Build Coastguard Worker     {
1404*8975f5c5SAndroid Build Coastguard Worker         if (mThreadIDs[serial] == id)
1405*8975f5c5SAndroid Build Coastguard Worker         {
1406*8975f5c5SAndroid Build Coastguard Worker             return serial + 1;
1407*8975f5c5SAndroid Build Coastguard Worker         }
1408*8975f5c5SAndroid Build Coastguard Worker     }
1409*8975f5c5SAndroid Build Coastguard Worker 
1410*8975f5c5SAndroid Build Coastguard Worker     mThreadIDs.push_back(id);
1411*8975f5c5SAndroid Build Coastguard Worker     return static_cast<uint32_t>(mThreadIDs.size());
1412*8975f5c5SAndroid Build Coastguard Worker }
1413*8975f5c5SAndroid Build Coastguard Worker 
1414*8975f5c5SAndroid Build Coastguard Worker namespace angle
1415*8975f5c5SAndroid Build Coastguard Worker {
GetHostTimeSeconds()1416*8975f5c5SAndroid Build Coastguard Worker double GetHostTimeSeconds()
1417*8975f5c5SAndroid Build Coastguard Worker {
1418*8975f5c5SAndroid Build Coastguard Worker     // Move the time origin to the first call to this function, to avoid generating unnecessarily
1419*8975f5c5SAndroid Build Coastguard Worker     // large timestamps.
1420*8975f5c5SAndroid Build Coastguard Worker     static double origin = GetCurrentSystemTime();
1421*8975f5c5SAndroid Build Coastguard Worker     return GetCurrentSystemTime() - origin;
1422*8975f5c5SAndroid Build Coastguard Worker }
1423*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
1424