Commit c43852aa by Jiacheng Lu Committed by Commit Bot

Various fixes for frame capture

1. Use contextId as identifier to separate captures for different GL context. 2. Fix write string params. In order to keep consistent between replay and capture, changes have been made to store C style string (with '\0' suffix) for string param capture, which breaks cpp frame capture. This change fixes it. 3. On Android device, it use a custom path to save captures and it breaks the loadBinaryData(). Here differentiate file name and file path to fix it. Bug: angleproject:3804 Change-Id: I378cf26697d15f0c1a8cf7afea2b758f5c58498b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1774469 Commit-Queue: Jiacheng Lu <lujc@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 80b1ba63
...@@ -8803,7 +8803,7 @@ egl::Error Context::unsetDefaultFramebuffer() ...@@ -8803,7 +8803,7 @@ egl::Error Context::unsetDefaultFramebuffer()
void Context::onPostSwap() const void Context::onPostSwap() const
{ {
// Dump frame capture if enabled. // Dump frame capture if enabled.
mFrameCapture->onEndFrame(); mFrameCapture->onEndFrame(this);
} }
// ErrorSet implementation. // ErrorSet implementation.
......
...@@ -60,17 +60,22 @@ ParamCapture::~ParamCapture() {} ...@@ -60,17 +60,22 @@ ParamCapture::~ParamCapture() {}
FrameCapture::FrameCapture() {} FrameCapture::FrameCapture() {}
FrameCapture::~FrameCapture() {} FrameCapture::~FrameCapture() {}
void FrameCapture::onEndFrame() {} void FrameCapture::onEndFrame(const gl::Context *context) {}
void FrameCapture::replay(gl::Context *context) {} void FrameCapture::replay(gl::Context *context) {}
#else #else
namespace namespace
{ {
std::string GetCaptureFileName(size_t frameIndex, const char *suffix) std::string GetCaptureFileName(int contextId, size_t frameIndex, const char *suffix)
{ {
std::stringstream fnameStream; std::stringstream fnameStream;
fnameStream << "angle_capture_frame" << std::setfill('0') << std::setw(3) << frameIndex fnameStream << "angle_capture_context" << contextId << "_frame" << std::setfill('0')
<< suffix; << std::setw(3) << frameIndex << suffix;
return ANGLE_CAPTURE_PATH + fnameStream.str(); return fnameStream.str();
}
std::string GetCaptureFilePath(int contextId, size_t frameIndex, const char *suffix)
{
return ANGLE_CAPTURE_PATH + GetCaptureFileName(contextId, frameIndex, suffix);
} }
void WriteParamStaticVarName(const CallCapture &call, void WriteParamStaticVarName(const CallCapture &call,
...@@ -100,7 +105,9 @@ constexpr size_t kInlineDataThreshold = 128; ...@@ -100,7 +105,9 @@ constexpr size_t kInlineDataThreshold = 128;
void WriteStringParamReplay(std::ostream &out, const ParamCapture &param) void WriteStringParamReplay(std::ostream &out, const ParamCapture &param)
{ {
const std::vector<uint8_t> &data = param.data[0]; const std::vector<uint8_t> &data = param.data[0];
std::string str(data.begin(), data.end()); // null terminate C style string
ASSERT(data.size() > 0 && data.back() == '\0');
std::string str(data.begin(), data.end() - 1);
out << "\"" << str << "\""; out << "\"" << str << "\"";
} }
} // anonymous namespace } // anonymous namespace
...@@ -417,17 +424,17 @@ bool FrameCapture::anyClientArray() const ...@@ -417,17 +424,17 @@ bool FrameCapture::anyClientArray() const
return false; return false;
} }
void FrameCapture::onEndFrame() void FrameCapture::onEndFrame(const gl::Context *context)
{ {
if (!mCalls.empty()) if (!mCalls.empty())
{ {
saveCapturedFrameAsCpp(); saveCapturedFrameAsCpp(context->id());
reset(); reset();
mFrameIndex++; mFrameIndex++;
} }
} }
void FrameCapture::saveCapturedFrameAsCpp() void FrameCapture::saveCapturedFrameAsCpp(int contextId)
{ {
bool useClientArrays = anyClientArray(); bool useClientArrays = anyClientArray();
...@@ -493,16 +500,17 @@ void FrameCapture::saveCapturedFrameAsCpp() ...@@ -493,16 +500,17 @@ void FrameCapture::saveCapturedFrameAsCpp()
if (!binaryData.empty()) if (!binaryData.empty())
{ {
std::string fname = GetCaptureFileName(mFrameIndex, ".angledata"); std::string dataFilepath = GetCaptureFilePath(contextId, mFrameIndex, ".angledata");
FILE *fp = fopen(fname.c_str(), "wb"); FILE *fp = fopen(dataFilepath.c_str(), "wb");
if (!fp) if (!fp)
{ {
FATAL() << "file " << fname << " can not be created!: " << strerror(errno); FATAL() << "file " << dataFilepath << " can not be created!: " << strerror(errno);
} }
fwrite(binaryData.data(), 1, binaryData.size(), fp); fwrite(binaryData.data(), 1, binaryData.size(), fp);
fclose(fp); fclose(fp);
std::string fname = GetCaptureFileName(contextId, mFrameIndex, ".angledata");
header << "std::vector<uint8_t> gBinaryData;\n"; header << "std::vector<uint8_t> gBinaryData;\n";
header << "void LoadBinaryData()\n"; header << "void LoadBinaryData()\n";
header << "{\n"; header << "{\n";
...@@ -526,16 +534,16 @@ void FrameCapture::saveCapturedFrameAsCpp() ...@@ -526,16 +534,16 @@ void FrameCapture::saveCapturedFrameAsCpp()
std::string outString = out.str(); std::string outString = out.str();
std::string headerString = header.str(); std::string headerString = header.str();
std::string fname = GetCaptureFileName(mFrameIndex, ".cpp"); std::string cppFilePath = GetCaptureFilePath(contextId, mFrameIndex, ".cpp");
FILE *fp = fopen(fname.c_str(), "w"); FILE *fp = fopen(cppFilePath.c_str(), "w");
if (!fp) if (!fp)
{ {
FATAL() << "file " << fname << " can not be created!: " << strerror(errno); FATAL() << "file " << cppFilePath << " can not be created!: " << strerror(errno);
} }
fprintf(fp, "%s\n\n%s", headerString.c_str(), outString.c_str()); fprintf(fp, "%s\n\n%s", headerString.c_str(), outString.c_str());
fclose(fp); fclose(fp);
printf("Saved '%s'.\n", fname.c_str()); printf("Saved '%s'.\n", cppFilePath.c_str());
} }
int FrameCapture::getAndIncrementCounter(gl::EntryPoint entryPoint, const std::string &paramName) int FrameCapture::getAndIncrementCounter(gl::EntryPoint entryPoint, const std::string &paramName)
...@@ -557,7 +565,9 @@ void FrameCapture::writeStringPointerParamReplay(std::ostream &out, ...@@ -557,7 +565,9 @@ void FrameCapture::writeStringPointerParamReplay(std::ostream &out,
for (const std::vector<uint8_t> &data : param.data) for (const std::vector<uint8_t> &data : param.data)
{ {
std::string str(data.begin(), data.end()); // null terminate C style string
ASSERT(data.size() > 0 && data.back() == '\0');
std::string str(data.begin(), data.end() - 1);
header << " R\"(" << str << ")\",\n"; header << " R\"(" << str << ")\",\n";
} }
......
...@@ -156,7 +156,7 @@ class FrameCapture final : angle::NonCopyable ...@@ -156,7 +156,7 @@ class FrameCapture final : angle::NonCopyable
~FrameCapture(); ~FrameCapture();
void captureCall(const gl::Context *context, CallCapture &&call); void captureCall(const gl::Context *context, CallCapture &&call);
void onEndFrame(); void onEndFrame(const gl::Context *context);
bool enabled() const; bool enabled() const;
void replay(gl::Context *context); void replay(gl::Context *context);
...@@ -175,7 +175,7 @@ class FrameCapture final : angle::NonCopyable ...@@ -175,7 +175,7 @@ class FrameCapture final : angle::NonCopyable
void reset(); void reset();
int getAndIncrementCounter(gl::EntryPoint entryPoint, const std::string &paramName); int getAndIncrementCounter(gl::EntryPoint entryPoint, const std::string &paramName);
bool anyClientArray() const; bool anyClientArray() const;
void saveCapturedFrameAsCpp(); void saveCapturedFrameAsCpp(int contextId);
void writeStringPointerParamReplay(std::ostream &out, void writeStringPointerParamReplay(std::ostream &out,
std::ostream &header, std::ostream &header,
const CallCapture &call, const CallCapture &call,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment