| // |
| // Copyright 2019 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. |
| // |
| // FrameCapture.h: |
| // ANGLE Frame capture inteface. |
| // |
| |
| #ifndef LIBANGLE_FRAME_CAPTURE_H_ |
| #define LIBANGLE_FRAME_CAPTURE_H_ |
| |
| #include "common/PackedEnums.h" |
| #include "libANGLE/Context.h" |
| #include "libANGLE/angletypes.h" |
| #include "libANGLE/frame_capture_utils_autogen.h" |
| |
| #include <tuple> |
| |
| namespace angle |
| { |
| struct ParamCapture : angle::NonCopyable |
| { |
| ParamCapture(); |
| ParamCapture(const char *nameIn, ParamType typeIn); |
| ~ParamCapture(); |
| |
| ParamCapture(ParamCapture &&other); |
| ParamCapture &operator=(ParamCapture &&other); |
| |
| std::string name; |
| ParamType type; |
| ParamValue value; |
| std::vector<std::vector<uint8_t>> data; |
| int arrayClientPointerIndex = -1; |
| size_t readBufferSize = 0; |
| }; |
| |
| class ParamBuffer final : angle::NonCopyable |
| { |
| public: |
| ParamBuffer(); |
| ~ParamBuffer(); |
| |
| ParamBuffer(ParamBuffer &&other); |
| ParamBuffer &operator=(ParamBuffer &&other); |
| |
| template <typename T> |
| void addValueParam(const char *paramName, ParamType paramType, T paramValue); |
| |
| ParamCapture &getParam(const char *paramName, ParamType paramType, int index); |
| |
| void addParam(ParamCapture &¶m); |
| bool hasClientArrayData() const { return mClientArrayDataParam != -1; } |
| ParamCapture &getClientArrayPointerParameter(); |
| size_t getReadBufferSize() const { return mReadBufferSize; } |
| |
| const std::vector<ParamCapture> &getParamCaptures() const { return mParamCaptures; } |
| |
| private: |
| std::vector<ParamCapture> mParamCaptures; |
| int mClientArrayDataParam = -1; |
| size_t mReadBufferSize = 0; |
| }; |
| |
| struct CallCapture |
| { |
| CallCapture(const char *nameIn, ParamBuffer &¶msIn); |
| ~CallCapture(); |
| |
| CallCapture(CallCapture &&other); |
| CallCapture &operator=(CallCapture &&other); |
| |
| std::string name; |
| ParamBuffer params; |
| }; |
| |
| class FrameCapture final : angle::NonCopyable |
| { |
| public: |
| FrameCapture(); |
| ~FrameCapture(); |
| |
| void captureCall(const gl::Context *context, CallCapture &&call); |
| void onEndFrame(); |
| bool enabled() const; |
| |
| private: |
| // <CallName, ParamName> |
| using Counter = std::tuple<std::string, std::string>; |
| |
| void captureClientArraySnapshot(const gl::Context *context, |
| size_t vertexCount, |
| size_t instanceCount); |
| |
| void writeCallReplay(const CallCapture &call, |
| std::ostream &out, |
| std::ostream &header, |
| std::vector<uint8_t> *binaryData); |
| void reset(); |
| int getAndIncrementCounter(const std::string &callName, const std::string ¶mName); |
| bool anyClientArray() const; |
| void saveCapturedFrameAsCpp(); |
| |
| std::vector<CallCapture> mCalls; |
| gl::AttribArray<int> mClientVertexArrayMap; |
| size_t mFrameIndex; |
| gl::AttribArray<size_t> mClientArraySizes; |
| std::map<Counter, int> mDataCounters; |
| size_t mReadBufferSize; |
| }; |
| |
| template <typename CaptureFuncT, typename ValidationFuncT, typename... ArgsT> |
| void CaptureCallToFrameCapture(const char *entryPointName, |
| CaptureFuncT captureFunc, |
| ValidationFuncT validationFunc, |
| gl::Context *context, |
| ArgsT... captureParams) |
| { |
| FrameCapture *frameCapture = context->getFrameCapture(); |
| if (!frameCapture->enabled()) |
| return; |
| |
| bool isCallValid = validationFunc(context, captureParams...); |
| CallCapture call = captureFunc(context, isCallValid, captureParams...); |
| frameCapture->captureCall(context, std::move(call)); |
| } |
| |
| template <typename T> |
| void ParamBuffer::addValueParam(const char *paramName, ParamType paramType, T paramValue) |
| { |
| ParamCapture capture(paramName, paramType); |
| InitParamValue(paramType, paramValue, &capture.value); |
| mParamCaptures.emplace_back(std::move(capture)); |
| } |
| |
| std::ostream &operator<<(std::ostream &os, const ParamCapture &capture); |
| |
| // Pointer capture helpers. |
| void CaptureMemory(const void *source, size_t size, ParamCapture *paramCapture); |
| void CaptureString(const GLchar *str, ParamCapture *paramCapture); |
| |
| template <ParamType ParamT, typename T> |
| void WriteParamValueToStream(std::ostream &os, T value); |
| |
| template <> |
| void WriteParamValueToStream<ParamType::TGLboolean>(std::ostream &os, GLboolean value); |
| |
| template <> |
| void WriteParamValueToStream<ParamType::TvoidConstPointer>(std::ostream &os, const void *value); |
| |
| template <> |
| void WriteParamValueToStream<ParamType::TGLDEBUGPROCKHR>(std::ostream &os, GLDEBUGPROCKHR value); |
| |
| // General fallback for any unspecific type. |
| template <ParamType ParamT, typename T> |
| void WriteParamValueToStream(std::ostream &os, T value) |
| { |
| os << value; |
| } |
| } // namespace angle |
| |
| #endif // LIBANGLE_FRAME_CAPTURE_H_ |