File: frame_capture_test_utils.h

package info (click to toggle)
webkit2gtk 2.51.2-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 457,708 kB
  • sloc: cpp: 3,884,629; javascript: 198,661; ansic: 165,298; python: 49,171; asm: 21,849; ruby: 18,095; perl: 16,914; xml: 4,623; sh: 2,397; yacc: 2,356; java: 2,019; lex: 1,330; pascal: 372; makefile: 197
file content (269 lines) | stat: -rw-r--r-- 7,943 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
//
// Copyright 2020 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.
//
// frame_capture_test_utils:
//   Helper functions for capture and replay of traces.
//

#ifndef UTIL_CAPTURE_FRAME_CAPTURE_TEST_UTILS_H_
#define UTIL_CAPTURE_FRAME_CAPTURE_TEST_UTILS_H_

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_libc_calls
#endif

#include <iostream>
#include <map>
#include <memory>
#include <sstream>
#include <type_traits>
#include <vector>

#include "common/angleutils.h"
#include "common/debug.h"
#include "common/frame_capture_binary_data.h"
#include "common/frame_capture_utils.h"
#include "common/system_utils.h"
#include "trace_interface.h"

#define USE_SYSTEM_ZLIB
#include "compression_utils_portable.h"

#define ANGLE_MACRO_STRINGIZE_AUX(a) #a
#define ANGLE_MACRO_STRINGIZE(a) ANGLE_MACRO_STRINGIZE_AUX(a)
#define ANGLE_MACRO_CONCAT_AUX(a, b) a##b
#define ANGLE_MACRO_CONCAT(a, b) ANGLE_MACRO_CONCAT_AUX(a, b)

namespace angle
{

using ValidateSerializedStateCallback = void (*)(const char *, const char *, uint32_t);

using GetSerializedContextStateFunc          = const char *(*)(uint32_t);
using SetValidateSerializedStateCallbackFunc = void (*)(ValidateSerializedStateCallback);
using SetupEntryPoints = void (*)(angle::TraceCallbacks *, angle::TraceFunctions **);

class TraceLibrary : angle::NonCopyable, angle::TraceCallbacks
{
  public:
    TraceLibrary(const std::string &traceName,
                 const TraceInfo &traceInfo,
                 const std::string &baseDir);

    bool valid() const
    {
        return (mTraceLibrary != nullptr) && (mTraceLibrary->getNative() != nullptr);
    }

    void setReplayResourceMode(const bool resourceMode)
    {
        mTraceFunctions->SetReplayResourceMode(
            (resourceMode ? ReplayResourceMode::All : ReplayResourceMode::Active));
    }

    void setBinaryDataDir(const char *dataDir)
    {
        mBinaryDataDir = dataDir;
        mTraceFunctions->SetBinaryDataDir(dataDir);
    }

    void setDebugOutputDir(const char *dataDir) { mDebugOutputDir = dataDir; }

    void replayFrame(uint32_t frameIndex) { mTraceFunctions->ReplayFrame(frameIndex); }

    void setupReplay() { mTraceFunctions->SetupReplay(); }

    void resetReplay() { mTraceFunctions->ResetReplay(); }

    void finishReplay()
    {
        mTraceFunctions->FinishReplay();
        mBinaryData = {};  // set to empty vector to release memory.
    }

    void setupFirstFrame() { mTraceFunctions->SetupFirstFrame(); }

    const char *getSerializedContextState(uint32_t frameIndex)
    {
        return callFunc<GetSerializedContextStateFunc>("GetSerializedContextState", frameIndex);
    }

    void setValidateSerializedStateCallback(ValidateSerializedStateCallback callback)
    {
        return callFunc<SetValidateSerializedStateCallbackFunc>(
            "SetValidateSerializedStateCallback", callback);
    }

    void setTraceGzPath(const std::string &traceGzPath)
    {
        mTraceFunctions->SetTraceGzPath(traceGzPath);
    }

  private:
    template <typename FuncT, typename... ArgsT>
    typename std::invoke_result<FuncT, ArgsT...>::type callFunc(const char *funcName, ArgsT... args)
    {
        void *untypedFunc = mTraceLibrary->getSymbol(funcName);
        if (!untypedFunc)
        {
            fprintf(stderr, "Error loading function: %s\n", funcName);
            ASSERT(untypedFunc);
        }
        auto typedFunc = reinterpret_cast<FuncT>(untypedFunc);
        return typedFunc(args...);
    }

    FrameCaptureBinaryData *ConfigureBinaryDataLoader(const char *fileName) override;
    uint8_t *LoadBinaryData(const char *fileName) override;

    std::unique_ptr<Library> mTraceLibrary;
    std::vector<uint8_t> mBinaryData;
    std::string mBinaryDataDir;
    std::string mDebugOutputDir;
    angle::TraceInfo mTraceInfo;
    angle::TraceFunctions *mTraceFunctions = nullptr;
};

bool LoadTraceNamesFromJSON(const std::string jsonFilePath, std::vector<std::string> *namesOut);
bool LoadTraceInfoFromJSON(const std::string &traceName,
                           const std::string &traceJsonPath,
                           TraceInfo *traceInfoOut);

using TraceFunction    = std::vector<CallCapture>;
using TraceFunctionMap = std::map<std::string, TraceFunction>;

void ReplayTraceFunctionCall(const CallCapture &call, const TraceFunctionMap &customFunctions);
void ReplayCustomFunctionCall(const CallCapture &call, const TraceFunctionMap &customFunctions);

template <typename T>
struct AssertFalse : std::false_type
{};

GLuint GetResourceIDMapValue(ResourceIDType resourceIDType, GLuint key);

template <typename T>
T GetParamValue(ParamType type, const ParamValue &value);

template <>
inline GLuint GetParamValue<GLuint>(ParamType type, const ParamValue &value)
{
    ResourceIDType resourceIDType = GetResourceIDTypeFromParamType(type);
    if (resourceIDType == ResourceIDType::InvalidEnum)
    {
        return value.GLuintVal;
    }
    else
    {
        return GetResourceIDMapValue(resourceIDType, value.GLuintVal);
    }
}

template <>
inline GLint GetParamValue<GLint>(ParamType type, const ParamValue &value)
{
    return value.GLintVal;
}

template <>
inline const void *GetParamValue<const void *>(ParamType type, const ParamValue &value)
{
    return value.voidConstPointerVal;
}

template <>
inline GLuint64 GetParamValue<GLuint64>(ParamType type, const ParamValue &value)
{
    return value.GLuint64Val;
}

template <>
inline GLint64 GetParamValue<GLint64>(ParamType type, const ParamValue &value)
{
    return value.GLint64Val;
}

template <>
inline const char *GetParamValue<const char *>(ParamType type, const ParamValue &value)
{
    return value.GLcharConstPointerVal;
}

template <>
inline void *GetParamValue<void *>(ParamType type, const ParamValue &value)
{
    return value.voidPointerVal;
}

#if defined(ANGLE_IS_64_BIT_CPU)
template <>
inline const EGLAttrib *GetParamValue<const EGLAttrib *>(ParamType type, const ParamValue &value)
{
    return value.EGLAttribConstPointerVal;
}
#endif  // defined(ANGLE_IS_64_BIT_CPU)

template <>
inline const EGLint *GetParamValue<const EGLint *>(ParamType type, const ParamValue &value)
{
    return value.EGLintConstPointerVal;
}

template <>
inline const GLchar *const *GetParamValue<const GLchar *const *>(ParamType type,
                                                                 const ParamValue &value)
{
    return value.GLcharConstPointerPointerVal;
}

// On Apple platforms, std::is_same<uint64_t, long> is false despite being both 8 bits.
#if defined(ANGLE_PLATFORM_APPLE) || !defined(ANGLE_IS_64_BIT_CPU)
template <>
inline long GetParamValue<long>(ParamType type, const ParamValue &value)
{
    return static_cast<long>(value.GLint64Val);
}

template <>
inline unsigned long GetParamValue<unsigned long>(ParamType type, const ParamValue &value)
{
    return static_cast<unsigned long>(value.GLuint64Val);
}
#endif  // defined(ANGLE_PLATFORM_APPLE)

template <typename T>
T GetParamValue(ParamType type, const ParamValue &value)
{
    static_assert(AssertFalse<T>::value, "No specialization for type.");
}

template <typename T>
struct Traits;

template <typename... Args>
struct Traits<void(Args...)>
{
    static constexpr size_t NArgs = sizeof...(Args);
    template <size_t Idx>
    struct Arg
    {
        typedef typename std::tuple_element<Idx, std::tuple<Args...>>::type Type;
    };
};

template <typename Fn, size_t Idx>
using FnArg = typename Traits<Fn>::template Arg<Idx>::Type;

template <typename Fn, size_t NArgs>
using EnableIfNArgs = typename std::enable_if_t<Traits<Fn>::NArgs == NArgs, int>;

template <typename Fn, size_t Idx>
FnArg<Fn, Idx> Arg(const Captures &cap)
{
    ASSERT(Idx < cap.size());
    return GetParamValue<FnArg<Fn, Idx>>(cap[Idx].type, cap[Idx].value);
}
}  // namespace angle

#endif  // UTIL_CAPTURE_FRAME_CAPTURE_TEST_UTILS_H_