1
2 // Copyright 2019 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 // FrameCapture.h:
7 // ANGLE Frame capture inteface.
8 //
9
10 #ifndef LIBANGLE_FRAME_CAPTURE_H_
11 #define LIBANGLE_FRAME_CAPTURE_H_
12
13 #include "common/PackedEnums.h"
14 #include "libANGLE/Context.h"
15 #include "libANGLE/angletypes.h"
16 #include "libANGLE/entry_points_utils.h"
17 #include "libANGLE/frame_capture_utils_autogen.h"
18
19 #include <tuple>
20
21 namespace gl
22 {
23 enum class GLenumGroup;
24 }
25
26 namespace angle
27 {
28 struct ParamCapture : angle::NonCopyable
29 {
30 ParamCapture();
31 ParamCapture(const char *nameIn, ParamType typeIn);
32 ~ParamCapture();
33
34 ParamCapture(ParamCapture &&other);
35 ParamCapture &operator=(ParamCapture &&other);
36
37 std::string name;
38 ParamType type;
39 ParamValue value;
40 gl::GLenumGroup enumGroup; // only used for param type GLenum, GLboolean and GLbitfield
41 std::vector<std::vector<uint8_t>> data;
42 int arrayClientPointerIndex = -1;
43 size_t readBufferSizeBytes = 0;
44 };
45
46 class ParamBuffer final : angle::NonCopyable
47 {
48 public:
49 ParamBuffer();
50 ~ParamBuffer();
51
52 ParamBuffer(ParamBuffer &&other);
53 ParamBuffer &operator=(ParamBuffer &&other);
54
55 template <typename T>
56 void addValueParam(const char *paramName, ParamType paramType, T paramValue);
57 template <typename T>
58 void addEnumParam(const char *paramName,
59 gl::GLenumGroup enumGroup,
60 ParamType paramType,
61 T paramValue);
62
63 ParamCapture &getParam(const char *paramName, ParamType paramType, int index);
64
65 void addParam(ParamCapture &¶m);
66 void addReturnValue(ParamCapture &&returnValue);
hasClientArrayData()67 bool hasClientArrayData() const { return mClientArrayDataParam != -1; }
68 ParamCapture &getClientArrayPointerParameter();
getReadBufferSize()69 size_t getReadBufferSize() const { return mReadBufferSize; }
70
getParamCaptures()71 const std::vector<ParamCapture> &getParamCaptures() const { return mParamCaptures; }
72
73 private:
74 std::vector<ParamCapture> mParamCaptures;
75 ParamCapture mReturnValueCapture;
76 int mClientArrayDataParam = -1;
77 size_t mReadBufferSize = 0;
78 };
79
80 struct CallCapture
81 {
82 CallCapture(gl::EntryPoint entryPointIn, ParamBuffer &¶msIn);
83 CallCapture(const std::string &customFunctionNameIn, ParamBuffer &¶msIn);
84 ~CallCapture();
85
86 CallCapture(CallCapture &&other);
87 CallCapture &operator=(CallCapture &&other);
88
89 const char *name() const;
90
91 gl::EntryPoint entryPoint;
92 std::string customFunctionName;
93 ParamBuffer params;
94 };
95
96 class FrameCapture final : angle::NonCopyable
97 {
98 public:
99 FrameCapture();
100 ~FrameCapture();
101
102 void captureCall(const gl::Context *context, CallCapture &&call);
103 void onEndFrame();
104 bool enabled() const;
105
106 private:
107 // <CallName, ParamName>
108 using Counter = std::tuple<gl::EntryPoint, std::string>;
109
110 void captureClientArraySnapshot(const gl::Context *context,
111 size_t vertexCount,
112 size_t instanceCount);
113
114 void writeCallReplay(const CallCapture &call,
115 std::ostream &out,
116 std::ostream &header,
117 std::vector<uint8_t> *binaryData);
118 void reset();
119 int getAndIncrementCounter(gl::EntryPoint entryPoint, const std::string ¶mName);
120 bool anyClientArray() const;
121 void saveCapturedFrameAsCpp();
122
123 std::vector<CallCapture> mCalls;
124 gl::AttribArray<int> mClientVertexArrayMap;
125 size_t mFrameIndex;
126 gl::AttribArray<size_t> mClientArraySizes;
127 std::map<Counter, int> mDataCounters;
128 size_t mReadBufferSize;
129 };
130
131 template <typename CaptureFuncT, typename... ArgsT>
CaptureCallToFrameCapture(CaptureFuncT captureFunc,bool isCallValid,gl::Context * context,ArgsT...captureParams)132 void CaptureCallToFrameCapture(CaptureFuncT captureFunc,
133 bool isCallValid,
134 gl::Context *context,
135 ArgsT... captureParams)
136 {
137 FrameCapture *frameCapture = context->getFrameCapture();
138 if (!frameCapture->enabled())
139 return;
140
141 CallCapture call = captureFunc(context, isCallValid, captureParams...);
142 frameCapture->captureCall(context, std::move(call));
143 }
144
145 template <typename T>
addValueParam(const char * paramName,ParamType paramType,T paramValue)146 void ParamBuffer::addValueParam(const char *paramName, ParamType paramType, T paramValue)
147 {
148 ParamCapture capture(paramName, paramType);
149 InitParamValue(paramType, paramValue, &capture.value);
150 mParamCaptures.emplace_back(std::move(capture));
151 }
152
153 template <typename T>
addEnumParam(const char * paramName,gl::GLenumGroup enumGroup,ParamType paramType,T paramValue)154 void ParamBuffer::addEnumParam(const char *paramName,
155 gl::GLenumGroup enumGroup,
156 ParamType paramType,
157 T paramValue)
158 {
159 ParamCapture capture(paramName, paramType);
160 InitParamValue(paramType, paramValue, &capture.value);
161 capture.enumGroup = enumGroup;
162 mParamCaptures.emplace_back(std::move(capture));
163 }
164
165 std::ostream &operator<<(std::ostream &os, const ParamCapture &capture);
166
167 // Pointer capture helpers.
168 void CaptureMemory(const void *source, size_t size, ParamCapture *paramCapture);
169 void CaptureString(const GLchar *str, ParamCapture *paramCapture);
170
171 template <ParamType ParamT, typename T>
172 void WriteParamValueToStream(std::ostream &os, T value);
173
174 template <>
175 void WriteParamValueToStream<ParamType::TGLboolean>(std::ostream &os, GLboolean value);
176
177 template <>
178 void WriteParamValueToStream<ParamType::TvoidConstPointer>(std::ostream &os, const void *value);
179
180 template <>
181 void WriteParamValueToStream<ParamType::TGLDEBUGPROCKHR>(std::ostream &os, GLDEBUGPROCKHR value);
182
183 template <>
184 void WriteParamValueToStream<ParamType::TGLDEBUGPROC>(std::ostream &os, GLDEBUGPROC value);
185
186 template <>
187 void WriteParamValueToStream<ParamType::TBufferID>(std::ostream &os, gl::BufferID value);
188
189 template <>
190 void WriteParamValueToStream<ParamType::TRenderbufferID>(std::ostream &os,
191 gl::RenderbufferID value);
192
193 template <>
194 void WriteParamValueToStream<ParamType::TTextureID>(std::ostream &os, gl::TextureID value);
195
196 // General fallback for any unspecific type.
197 template <ParamType ParamT, typename T>
WriteParamValueToStream(std::ostream & os,T value)198 void WriteParamValueToStream(std::ostream &os, T value)
199 {
200 os << value;
201 }
202 } // namespace angle
203
204 #endif // LIBANGLE_FRAME_CAPTURE_H_
205