• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &&param);
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 &&paramsIn);
83     CallCapture(const std::string &customFunctionNameIn, ParamBuffer &&paramsIn);
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 &paramName);
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