Hash :
af69179c
Author :
Date :
2019-07-30T17:22:22
Capture/Replay: Capture return values. This will allow us to record resource IDs as they are created and bound to OpenGL. This in turn will enable implementing mid-execution capture. Bug: angleproject:3611 Change-Id: I9f12eb0025d90ad86327cf5181efd831662c2e3f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1706562 Reviewed-by: Tim Van Patten <timvp@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
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
//
// 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 readBufferSizeBytes = 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);
void addReturnValue(ParamCapture &&returnValue);
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;
ParamCapture mReturnValueCapture;
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... ArgsT>
void CaptureCallToFrameCapture(const char *entryPointName,
CaptureFuncT captureFunc,
bool isCallValid,
gl::Context *context,
ArgsT... captureParams)
{
FrameCapture *frameCapture = context->getFrameCapture();
if (!frameCapture->enabled())
return;
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);
template <>
void WriteParamValueToStream<ParamType::TGLDEBUGPROC>(std::ostream &os, GLDEBUGPROC 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_