xref: /aosp_15_r20/external/angle/util/capture/frame_capture_test_utils.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 <map>
15 #include <memory>
16 #include <sstream>
17 #include <type_traits>
18 #include <vector>
19 
20 #include "common/angleutils.h"
21 #include "common/debug.h"
22 #include "common/frame_capture_utils.h"
23 #include "common/system_utils.h"
24 #include "trace_interface.h"
25 
26 #define USE_SYSTEM_ZLIB
27 #include "compression_utils_portable.h"
28 
29 #define ANGLE_MACRO_STRINGIZE_AUX(a) #a
30 #define ANGLE_MACRO_STRINGIZE(a) ANGLE_MACRO_STRINGIZE_AUX(a)
31 #define ANGLE_MACRO_CONCAT_AUX(a, b) a##b
32 #define ANGLE_MACRO_CONCAT(a, b) ANGLE_MACRO_CONCAT_AUX(a, b)
33 
34 namespace angle
35 {
36 
37 using ValidateSerializedStateCallback = void (*)(const char *, const char *, uint32_t);
38 
39 using GetSerializedContextStateFunc          = const char *(*)(uint32_t);
40 using SetValidateSerializedStateCallbackFunc = void (*)(ValidateSerializedStateCallback);
41 using SetupEntryPoints = void (*)(angle::TraceCallbacks *, angle::TraceFunctions **);
42 
43 class TraceLibrary : angle::NonCopyable, angle::TraceCallbacks
44 {
45   public:
46     TraceLibrary(const std::string &traceName,
47                  const TraceInfo &traceInfo,
48                  const std::string &baseDir);
49 
valid()50     bool valid() const
51     {
52         return (mTraceLibrary != nullptr) && (mTraceLibrary->getNative() != nullptr);
53     }
54 
setReplayResourceMode(const bool resourceMode)55     void setReplayResourceMode(const bool resourceMode)
56     {
57         mTraceFunctions->SetReplayResourceMode(
58             (resourceMode ? ReplayResourceMode::All : ReplayResourceMode::Active));
59     }
60 
setBinaryDataDir(const char * dataDir)61     void setBinaryDataDir(const char *dataDir)
62     {
63         mBinaryDataDir = dataDir;
64         mTraceFunctions->SetBinaryDataDir(dataDir);
65     }
66 
setDebugOutputDir(const char * dataDir)67     void setDebugOutputDir(const char *dataDir) { mDebugOutputDir = dataDir; }
68 
replayFrame(uint32_t frameIndex)69     void replayFrame(uint32_t frameIndex) { mTraceFunctions->ReplayFrame(frameIndex); }
70 
setupReplay()71     void setupReplay() { mTraceFunctions->SetupReplay(); }
72 
resetReplay()73     void resetReplay() { mTraceFunctions->ResetReplay(); }
74 
finishReplay()75     void finishReplay()
76     {
77         mTraceFunctions->FinishReplay();
78         mBinaryData = {};  // set to empty vector to release memory.
79     }
80 
getSerializedContextState(uint32_t frameIndex)81     const char *getSerializedContextState(uint32_t frameIndex)
82     {
83         return callFunc<GetSerializedContextStateFunc>("GetSerializedContextState", frameIndex);
84     }
85 
setValidateSerializedStateCallback(ValidateSerializedStateCallback callback)86     void setValidateSerializedStateCallback(ValidateSerializedStateCallback callback)
87     {
88         return callFunc<SetValidateSerializedStateCallbackFunc>(
89             "SetValidateSerializedStateCallback", callback);
90     }
91 
setTraceGzPath(const std::string & traceGzPath)92     void setTraceGzPath(const std::string &traceGzPath)
93     {
94         mTraceFunctions->SetTraceGzPath(traceGzPath);
95     }
96 
97   private:
98     template <typename FuncT, typename... ArgsT>
callFunc(const char * funcName,ArgsT...args)99     typename std::invoke_result<FuncT, ArgsT...>::type callFunc(const char *funcName, ArgsT... args)
100     {
101         void *untypedFunc = mTraceLibrary->getSymbol(funcName);
102         if (!untypedFunc)
103         {
104             fprintf(stderr, "Error loading function: %s\n", funcName);
105             ASSERT(untypedFunc);
106         }
107         auto typedFunc = reinterpret_cast<FuncT>(untypedFunc);
108         return typedFunc(args...);
109     }
110 
111     uint8_t *LoadBinaryData(const char *fileName) override;
112 
113     std::unique_ptr<Library> mTraceLibrary;
114     std::vector<uint8_t> mBinaryData;
115     std::string mBinaryDataDir;
116     std::string mDebugOutputDir;
117     angle::TraceInfo mTraceInfo;
118     angle::TraceFunctions *mTraceFunctions = nullptr;
119 };
120 
121 bool LoadTraceNamesFromJSON(const std::string jsonFilePath, std::vector<std::string> *namesOut);
122 bool LoadTraceInfoFromJSON(const std::string &traceName,
123                            const std::string &traceJsonPath,
124                            TraceInfo *traceInfoOut);
125 
126 using TraceFunction    = std::vector<CallCapture>;
127 using TraceFunctionMap = std::map<std::string, TraceFunction>;
128 
129 void ReplayTraceFunctionCall(const CallCapture &call, const TraceFunctionMap &customFunctions);
130 void ReplayCustomFunctionCall(const CallCapture &call, const TraceFunctionMap &customFunctions);
131 
132 template <typename T>
133 struct AssertFalse : std::false_type
134 {};
135 
136 GLuint GetResourceIDMapValue(ResourceIDType resourceIDType, GLuint key);
137 
138 template <typename T>
139 T GetParamValue(ParamType type, const ParamValue &value);
140 
141 template <>
142 inline GLuint GetParamValue<GLuint>(ParamType type, const ParamValue &value)
143 {
144     ResourceIDType resourceIDType = GetResourceIDTypeFromParamType(type);
145     if (resourceIDType == ResourceIDType::InvalidEnum)
146     {
147         return value.GLuintVal;
148     }
149     else
150     {
151         return GetResourceIDMapValue(resourceIDType, value.GLuintVal);
152     }
153 }
154 
155 template <>
156 inline GLint GetParamValue<GLint>(ParamType type, const ParamValue &value)
157 {
158     return value.GLintVal;
159 }
160 
161 template <>
162 inline const void *GetParamValue<const void *>(ParamType type, const ParamValue &value)
163 {
164     return value.voidConstPointerVal;
165 }
166 
167 template <>
168 inline GLuint64 GetParamValue<GLuint64>(ParamType type, const ParamValue &value)
169 {
170     return value.GLuint64Val;
171 }
172 
173 template <>
174 inline GLint64 GetParamValue<GLint64>(ParamType type, const ParamValue &value)
175 {
176     return value.GLint64Val;
177 }
178 
179 template <>
180 inline const char *GetParamValue<const char *>(ParamType type, const ParamValue &value)
181 {
182     return value.GLcharConstPointerVal;
183 }
184 
185 template <>
186 inline void *GetParamValue<void *>(ParamType type, const ParamValue &value)
187 {
188     return value.voidPointerVal;
189 }
190 
191 #if defined(ANGLE_IS_64_BIT_CPU)
192 template <>
193 inline const EGLAttrib *GetParamValue<const EGLAttrib *>(ParamType type, const ParamValue &value)
194 {
195     return value.EGLAttribConstPointerVal;
196 }
197 #endif  // defined(ANGLE_IS_64_BIT_CPU)
198 
199 template <>
200 inline const EGLint *GetParamValue<const EGLint *>(ParamType type, const ParamValue &value)
201 {
202     return value.EGLintConstPointerVal;
203 }
204 
205 template <>
206 inline const GLchar *const *GetParamValue<const GLchar *const *>(ParamType type,
207                                                                  const ParamValue &value)
208 {
209     return value.GLcharConstPointerPointerVal;
210 }
211 
212 // On Apple platforms, std::is_same<uint64_t, long> is false despite being both 8 bits.
213 #if defined(ANGLE_PLATFORM_APPLE) || !defined(ANGLE_IS_64_BIT_CPU)
214 template <>
215 inline long GetParamValue<long>(ParamType type, const ParamValue &value)
216 {
217     return static_cast<long>(value.GLint64Val);
218 }
219 
220 template <>
221 inline unsigned long GetParamValue<unsigned long>(ParamType type, const ParamValue &value)
222 {
223     return static_cast<unsigned long>(value.GLuint64Val);
224 }
225 #endif  // defined(ANGLE_PLATFORM_APPLE)
226 
227 template <typename T>
GetParamValue(ParamType type,const ParamValue & value)228 T GetParamValue(ParamType type, const ParamValue &value)
229 {
230     static_assert(AssertFalse<T>::value, "No specialization for type.");
231 }
232 
233 template <typename T>
234 struct Traits;
235 
236 template <typename... Args>
237 struct Traits<void(Args...)>
238 {
239     static constexpr size_t NArgs = sizeof...(Args);
240     template <size_t Idx>
241     struct Arg
242     {
243         typedef typename std::tuple_element<Idx, std::tuple<Args...>>::type Type;
244     };
245 };
246 
247 template <typename Fn, size_t Idx>
248 using FnArg = typename Traits<Fn>::template Arg<Idx>::Type;
249 
250 template <typename Fn, size_t NArgs>
251 using EnableIfNArgs = typename std::enable_if_t<Traits<Fn>::NArgs == NArgs, int>;
252 
253 template <typename Fn, size_t Idx>
254 FnArg<Fn, Idx> Arg(const Captures &cap)
255 {
256     ASSERT(Idx < cap.size());
257     return GetParamValue<FnArg<Fn, Idx>>(cap[Idx].type, cap[Idx].value);
258 }
259 }  // namespace angle
260 
261 #endif  // UTIL_CAPTURE_FRAME_CAPTURE_TEST_UTILS_H_
262