1 //
2 // Copyright 2020 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 // frame_capture_test_utils:
7 // Helper functions for capture and replay of traces.
8 //
9
10 #ifndef UTIL_CAPTURE_FRAME_CAPTURE_TEST_UTILS_H_
11 #define UTIL_CAPTURE_FRAME_CAPTURE_TEST_UTILS_H_
12
13 #include <iostream>
14 #include <memory>
15 #include <sstream>
16 #include <type_traits>
17 #include <vector>
18
19 #include "common/angleutils.h"
20 #include "common/debug.h"
21 #include "common/system_utils.h"
22
23 #define USE_SYSTEM_ZLIB
24 #include "compression_utils_portable.h"
25
26 #define ANGLE_MACRO_STRINGIZE_AUX(a) #a
27 #define ANGLE_MACRO_STRINGIZE(a) ANGLE_MACRO_STRINGIZE_AUX(a)
28 #define ANGLE_MACRO_CONCAT_AUX(a, b) a##b
29 #define ANGLE_MACRO_CONCAT(a, b) ANGLE_MACRO_CONCAT_AUX(a, b)
30
31 namespace angle
32 {
33
DecompressBinaryData(const std::vector<uint8_t> & compressedData)34 inline uint8_t *DecompressBinaryData(const std::vector<uint8_t> &compressedData)
35 {
36 uint32_t uncompressedSize =
37 zlib_internal::GetGzipUncompressedSize(compressedData.data(), compressedData.size());
38
39 std::unique_ptr<uint8_t[]> uncompressedData(new uint8_t[uncompressedSize]);
40 uLong destLen = uncompressedSize;
41 int zResult =
42 zlib_internal::GzipUncompressHelper(uncompressedData.get(), &destLen, compressedData.data(),
43 static_cast<uLong>(compressedData.size()));
44
45 if (zResult != Z_OK)
46 {
47 std::cerr << "Failure to decompressed binary data: " << zResult << "\n";
48 return nullptr;
49 }
50
51 return uncompressedData.release();
52 }
53
54 using DecompressCallback = uint8_t *(*)(const std::vector<uint8_t> &);
55 using ValidateSerializedStateCallback = void (*)(const char *, const char *, uint32_t);
56
57 using SetBinaryDataDecompressCallbackFunc = void (*)(DecompressCallback);
58 using SetBinaryDataDirFunc = void (*)(const char *);
59 using SetupReplayFunc = void (*)();
60 using ReplayFrameFunc = void (*)(uint32_t);
61 using ResetReplayFunc = void (*)();
62 using FinishReplayFunc = void (*)();
63 using GetSerializedContextStateFunc = const char *(*)(uint32_t);
64 using SetValidateSerializedStateCallbackFunc = void (*)(ValidateSerializedStateCallback);
65
66 class TraceLibrary
67 {
68 public:
TraceLibrary(const char * traceNameIn)69 TraceLibrary(const char *traceNameIn)
70 {
71 std::stringstream traceNameStr;
72 #if !defined(ANGLE_PLATFORM_WINDOWS)
73 traceNameStr << "lib";
74 #endif // !defined(ANGLE_PLATFORM_WINDOWS)
75 traceNameStr << traceNameIn;
76 #if defined(ANGLE_PLATFORM_ANDROID) && defined(COMPONENT_BUILD)
77 // Added to shared library names in Android component builds in
78 // https://chromium.googlesource.com/chromium/src/+/9bacc8c4868cc802f69e1e858eea6757217a508f/build/toolchain/toolchain.gni#56
79 traceNameStr << ".cr";
80 #endif // defined(ANGLE_PLATFORM_ANDROID) && defined(COMPONENT_BUILD)
81 std::string traceName = traceNameStr.str();
82 mTraceLibrary.reset(OpenSharedLibrary(traceName.c_str(), SearchType::ModuleDir));
83 }
84
valid()85 bool valid() const
86 {
87 return (mTraceLibrary != nullptr) && (mTraceLibrary->getNative() != nullptr);
88 }
89
setBinaryDataDir(const char * dataDir)90 void setBinaryDataDir(const char *dataDir)
91 {
92 callFunc<SetBinaryDataDirFunc>("SetBinaryDataDir", dataDir);
93 }
94
setBinaryDataDecompressCallback(DecompressCallback callback)95 void setBinaryDataDecompressCallback(DecompressCallback callback)
96 {
97 callFunc<SetBinaryDataDecompressCallbackFunc>("SetBinaryDataDecompressCallback", callback);
98 }
99
replayFrame(uint32_t frameIndex)100 void replayFrame(uint32_t frameIndex) { callFunc<ReplayFrameFunc>("ReplayFrame", frameIndex); }
101
setupReplay()102 void setupReplay() { callFunc<SetupReplayFunc>("SetupReplay"); }
103
resetReplay()104 void resetReplay() { callFunc<ResetReplayFunc>("ResetReplay"); }
105
finishReplay()106 void finishReplay() { callFunc<FinishReplayFunc>("FinishReplay"); }
107
getSerializedContextState(uint32_t frameIndex)108 const char *getSerializedContextState(uint32_t frameIndex)
109 {
110 return callFunc<GetSerializedContextStateFunc>("GetSerializedContextState", frameIndex);
111 }
112
setValidateSerializedStateCallback(ValidateSerializedStateCallback callback)113 void setValidateSerializedStateCallback(ValidateSerializedStateCallback callback)
114 {
115 return callFunc<SetValidateSerializedStateCallbackFunc>(
116 "SetValidateSerializedStateCallback", callback);
117 }
118
119 private:
120 template <typename FuncT, typename... ArgsT>
callFunc(const char * funcName,ArgsT...args)121 typename std::result_of<FuncT(ArgsT...)>::type callFunc(const char *funcName, ArgsT... args)
122 {
123 void *untypedFunc = mTraceLibrary->getSymbol(funcName);
124 if (!untypedFunc)
125 {
126 fprintf(stderr, "Error loading function: %s\n", funcName);
127 ASSERT(untypedFunc);
128 }
129 auto typedFunc = reinterpret_cast<FuncT>(untypedFunc);
130 return typedFunc(args...);
131 }
132
133 std::unique_ptr<Library> mTraceLibrary;
134 };
135
136 static constexpr size_t kTraceInfoMaxNameLen = 128;
137
138 struct TraceInfo
139 {
140 char name[kTraceInfoMaxNameLen];
141 uint32_t contextClientMajorVersion;
142 uint32_t contextClientMinorVersion;
143 uint32_t frameStart;
144 uint32_t frameEnd;
145 uint32_t drawSurfaceWidth;
146 uint32_t drawSurfaceHeight;
147 uint32_t drawSurfaceColorSpace;
148 uint32_t displayPlatformType;
149 uint32_t displayDeviceType;
150 int configRedBits;
151 int configBlueBits;
152 int configGreenBits;
153 int configAlphaBits;
154 int configDepthBits;
155 int configStencilBits;
156 bool isBinaryDataCompressed;
157 bool areClientArraysEnabled;
158 bool isBindGeneratesResourcesEnabled;
159 bool isWebGLCompatibilityEnabled;
160 bool isRobustResourceInitEnabled;
161 };
162
163 bool LoadTraceNamesFromJSON(const std::string jsonFilePath, std::vector<std::string> *namesOut);
164 bool LoadTraceInfoFromJSON(const std::string &traceName,
165 const std::string &traceJsonPath,
166 TraceInfo *traceInfoOut);
167 } // namespace angle
168
169 #endif // UTIL_CAPTURE_FRAME_CAPTURE_TEST_UTILS_H_
170