• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2025 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // TracePerfTestCL:
7 //   Performance test for ANGLE CL replaying traces.
8 //
9 
10 #include "tests/perf_tests/ANGLEComputeTestCL.h"
11 #include "tests/perf_tests/TracePerfTest.h"
12 
13 #if defined(ANGLE_PLATFORM_ANDROID)
14 #    include "util/android/AndroidWindow.h"
15 #endif
16 
17 namespace angle
18 {
19 class TracePerfTestCL : public ANGLEComputeTestCL
20 {
21   public:
TracePerfTestCL(std::unique_ptr<const TracePerfParams> & params)22     TracePerfTestCL(std::unique_ptr<const TracePerfParams> &params)
23         : ANGLEComputeTestCL("TracePerf", *params.get(), "ms"),
24           mParams(std::move(params)),
25           mStartFrame(0),
26           mEndFrame(0)
27     {}
28 
29     void initializeBenchmark() override;
30     void drawBenchmark() override;
31     void destroyBenchmark() override;
32 
frameCount() const33     uint32_t frameCount() const
34     {
35         const TraceInfo &traceInfo = mParams->traceInfo;
36         return traceInfo.frameEnd - traceInfo.frameStart + 1;
37     }
38 
getStepAlignment() const39     int getStepAlignment() const override
40     {
41         // Align step counts to the number of frames in a trace.
42         return static_cast<int>(frameCount());
43     }
44 
TestBody()45     void TestBody() override { run(); }
46 
traceNameIs(const char * name) const47     bool traceNameIs(const char *name) const
48     {
49         return strncmp(name, mParams->traceInfo.name, kTraceInfoMaxNameLen) == 0;
50     }
51 
52   private:
53     std::unique_ptr<const TracePerfParams> mParams;
54 
55     uint32_t mStartFrame;
56     uint32_t mEndFrame;
57     uint32_t mCurrentFrame     = 0;
58     uint32_t mCurrentIteration = 0;
59     uint32_t mTotalFrameCount  = 0;
60     std::unique_ptr<TraceLibrary> mTraceReplay;
61 };
62 
CreateTracePerfTestCL(std::unique_ptr<const TracePerfParams> params)63 ANGLEPerfTest *CreateTracePerfTestCL(std::unique_ptr<const TracePerfParams> params)
64 {
65     return new TracePerfTestCL(params);
66 }
67 
FindTraceTestDataPath(const char * traceName,char * testDataDirOut,size_t maxDataDirLen)68 bool FindTraceTestDataPath(const char *traceName, char *testDataDirOut, size_t maxDataDirLen)
69 {
70     char relativeTestDataDir[kMaxPath] = {};
71     snprintf(relativeTestDataDir, kMaxPath, "%s%c%s", kTraceTestFolder, GetPathSeparator(),
72              traceName);
73     return angle::FindTestDataPath(relativeTestDataDir, testDataDirOut, maxDataDirLen);
74 }
75 
FindTraceGzPath(const std::string & traceName)76 std::string FindTraceGzPath(const std::string &traceName)
77 {
78     std::stringstream pathStream;
79 
80     char genDir[kMaxPath] = {};
81     if (!angle::FindTestDataPath("gen", genDir, kMaxPath))
82     {
83         return "";
84     }
85     pathStream << genDir << angle::GetPathSeparator() << "tracegz_" << traceName << ".gz";
86 
87     return pathStream.str();
88 }
89 
initializeBenchmark()90 void TracePerfTestCL::initializeBenchmark()
91 {
92     const TraceInfo &traceInfo = mParams->traceInfo;
93 
94     char testDataDir[kMaxPath] = {};
95     if (!FindTraceTestDataPath(traceInfo.name, testDataDir, kMaxPath))
96     {
97         failTest("Could not find test data folder.");
98         return;
99     }
100 
101     std::string baseDir = "";
102 #if defined(ANGLE_TRACE_EXTERNAL_BINARIES)
103     baseDir += AndroidWindow::GetApplicationDirectory() + "/angle_traces/";
104 #endif
105 
106     if (gTraceInterpreter)
107     {
108         mTraceReplay.reset(new TraceLibrary("angle_trace_interpreter", traceInfo, baseDir));
109         if (strcmp(gTraceInterpreter, "gz") == 0)
110         {
111             std::string traceGzPath = FindTraceGzPath(traceInfo.name);
112             if (traceGzPath.empty())
113             {
114                 failTest("Could not find trace gz.");
115                 return;
116             }
117             mTraceReplay->setTraceGzPath(traceGzPath);
118         }
119     }
120     else
121     {
122         std::stringstream traceNameStr;
123         traceNameStr << "angle_restricted_traces_" << traceInfo.name;
124         std::string traceName = traceNameStr.str();
125         mTraceReplay.reset(new TraceLibrary(traceNameStr.str(), traceInfo, baseDir));
126     }
127 
128     if (!mTraceReplay->valid())
129     {
130         failTest("Could not load trace.");
131         return;
132     }
133 
134     mStartFrame = traceInfo.frameStart;
135     mEndFrame   = traceInfo.frameEnd;
136     mTraceReplay->setBinaryDataDir(testDataDir);
137     mTraceReplay->setReplayResourceMode(gIncludeInactiveResources);
138     if (gScreenshotDir)
139     {
140         mTraceReplay->setDebugOutputDir(gScreenshotDir);
141     }
142 
143     mCurrentFrame     = mStartFrame;
144     mCurrentIteration = mStartFrame;
145 
146     // Potentially slow. Can load a lot of resources.
147     mTraceReplay->setupReplay();
148     ASSERT_GE(mEndFrame, mStartFrame);
149 }
150 
destroyBenchmark()151 void TracePerfTestCL::destroyBenchmark()
152 {
153     mTraceReplay->finishReplay();
154     mTraceReplay.reset(nullptr);
155 }
156 
drawBenchmark()157 void TracePerfTestCL::drawBenchmark()
158 {
159     if (mCurrentFrame == mStartFrame)
160     {
161         mTraceReplay->setupFirstFrame();
162     }
163 
164     char frameName[32];
165     snprintf(frameName, sizeof(frameName), "Frame %u", mCurrentFrame);
166 
167     atraceCounter("TraceFrameIndex", mCurrentFrame);
168     mTraceReplay->replayFrame(mCurrentFrame);
169 
170     updatePerfCounters();
171 
172     mTotalFrameCount++;
173 
174     if (mCurrentFrame == mEndFrame)
175     {
176         mTraceReplay->resetReplay();
177         mCurrentFrame = mStartFrame;
178     }
179     else
180     {
181         mCurrentFrame++;
182     }
183 
184     // Always iterated for saving screenshots after reset
185     mCurrentIteration++;
186 }
187 
188 }  // namespace angle
189