blob: 2cac3abc392480349aeacdd660426f97cb49611b [file] [log] [blame]
//
// Copyright 2025 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// TracePerfTestCL:
// Performance test for ANGLE CL replaying traces.
//
#include "tests/perf_tests/ANGLEComputeTestCL.h"
#include "tests/perf_tests/TracePerfTest.h"
#if defined(ANGLE_PLATFORM_ANDROID)
# include "util/android/AndroidWindow.h"
#endif
namespace angle
{
class TracePerfTestCL : public ANGLEComputeTestCL
{
public:
TracePerfTestCL(std::unique_ptr<const TracePerfParams> &params)
: ANGLEComputeTestCL("TracePerf", *params.get(), "ms"),
mParams(std::move(params)),
mStartFrame(0),
mEndFrame(0)
{}
void initializeBenchmark() override;
void drawBenchmark() override;
void destroyBenchmark() override;
uint32_t frameCount() const
{
const TraceInfo &traceInfo = mParams->traceInfo;
return traceInfo.frameEnd - traceInfo.frameStart + 1;
}
int getStepAlignment() const override
{
// Align step counts to the number of frames in a trace.
return static_cast<int>(frameCount());
}
void TestBody() override { run(); }
bool traceNameIs(const char *name) const
{
return strncmp(name, mParams->traceInfo.name, kTraceInfoMaxNameLen) == 0;
}
private:
std::unique_ptr<const TracePerfParams> mParams;
uint32_t mStartFrame;
uint32_t mEndFrame;
uint32_t mCurrentFrame = 0;
uint32_t mCurrentIteration = 0;
uint32_t mTotalFrameCount = 0;
std::unique_ptr<TraceLibrary> mTraceReplay;
};
ANGLEPerfTest *CreateTracePerfTestCL(std::unique_ptr<const TracePerfParams> params)
{
return new TracePerfTestCL(params);
}
bool FindTraceTestDataPath(const char *traceName, char *testDataDirOut, size_t maxDataDirLen)
{
char relativeTestDataDir[kMaxPath] = {};
snprintf(relativeTestDataDir, kMaxPath, "%s%c%s", kTraceTestFolder, GetPathSeparator(),
traceName);
return angle::FindTestDataPath(relativeTestDataDir, testDataDirOut, maxDataDirLen);
}
std::string FindTraceGzPath(const std::string &traceName)
{
std::stringstream pathStream;
char genDir[kMaxPath] = {};
if (!angle::FindTestDataPath("gen", genDir, kMaxPath))
{
return "";
}
pathStream << genDir << angle::GetPathSeparator() << "tracegz_" << traceName << ".gz";
return pathStream.str();
}
void TracePerfTestCL::initializeBenchmark()
{
const TraceInfo &traceInfo = mParams->traceInfo;
char testDataDir[kMaxPath] = {};
if (!FindTraceTestDataPath(traceInfo.name, testDataDir, kMaxPath))
{
failTest("Could not find test data folder.");
return;
}
std::string baseDir = "";
#if defined(ANGLE_TRACE_EXTERNAL_BINARIES)
baseDir += AndroidWindow::GetApplicationDirectory() + "/angle_traces/";
#endif
if (gTraceInterpreter)
{
mTraceReplay.reset(new TraceLibrary("angle_trace_interpreter", traceInfo, baseDir));
if (strcmp(gTraceInterpreter, "gz") == 0)
{
std::string traceGzPath = FindTraceGzPath(traceInfo.name);
if (traceGzPath.empty())
{
failTest("Could not find trace gz.");
return;
}
mTraceReplay->setTraceGzPath(traceGzPath);
}
}
else
{
std::stringstream traceNameStr;
traceNameStr << "angle_restricted_traces_" << traceInfo.name;
std::string traceName = traceNameStr.str();
mTraceReplay.reset(new TraceLibrary(traceNameStr.str(), traceInfo, baseDir));
}
if (!mTraceReplay->valid())
{
failTest("Could not load trace.");
return;
}
mStartFrame = traceInfo.frameStart;
mEndFrame = traceInfo.frameEnd;
mTraceReplay->setBinaryDataDir(testDataDir);
mTraceReplay->setReplayResourceMode(gIncludeInactiveResources);
if (gScreenshotDir)
{
mTraceReplay->setDebugOutputDir(gScreenshotDir);
}
mCurrentFrame = mStartFrame;
mCurrentIteration = mStartFrame;
// Potentially slow. Can load a lot of resources.
mTraceReplay->setupReplay();
ASSERT_GE(mEndFrame, mStartFrame);
}
void TracePerfTestCL::destroyBenchmark()
{
mTraceReplay->finishReplay();
mTraceReplay.reset(nullptr);
}
void TracePerfTestCL::drawBenchmark()
{
if (mCurrentFrame == mStartFrame)
{
mTraceReplay->setupFirstFrame();
}
char frameName[32];
snprintf(frameName, sizeof(frameName), "Frame %u", mCurrentFrame);
atraceCounter("TraceFrameIndex", mCurrentFrame);
mTraceReplay->replayFrame(mCurrentFrame);
updatePerfCounters();
mTotalFrameCount++;
if (mCurrentFrame == mEndFrame)
{
mTraceReplay->resetReplay();
mCurrentFrame = mStartFrame;
}
else
{
mCurrentFrame++;
}
// Always iterated for saving screenshots after reset
mCurrentIteration++;
}
} // namespace angle