Expose replacement wrapper of CalculateLayout + (de)serialize layout inputs (#1575)

Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1575

If we want to replay layouts for benchmark, we should also capture the inputs. This diff does that as well as changing the API in CaptureTree.h. We now expose YGCalculateLayoutWithCapture designed to be a drop-in replacement for YGCalculateLayout. This allows us to have a bit more control on the order of everything and lets us capture measure functions in the next diff much easier.

Reviewed By: NickGerleman

Differential Revision: D53444261

fbshipit-source-id: 616e39153c21e7b472911502b6a717e92c88a4d1
This commit is contained in:
Joe Vilches
2024-02-09 16:44:32 -08:00
committed by Facebook GitHub Bot
parent 753b319977
commit cc66362a28
6 changed files with 66 additions and 16 deletions

View File

@@ -229,9 +229,14 @@ BenchmarkResult generateBenchmark(const std::filesystem::path& capturePath) {
YogaNodeAndConfig root = buildTreeFromJson(capture, nullptr, 0 /*index*/);
auto treeCreationEnd = steady_clock::now();
json layoutInputs = capture["layout-inputs"];
float availableWidth = layoutInputs["available-width"];
float availableHeight = layoutInputs["available-height"];
YGDirection direction = directionFromString(layoutInputs["owner-direction"]);
auto layoutBegin = steady_clock::now();
YGNodeCalculateLayout(
root.node_.get(), YGUndefined, YGUndefined, YGDirectionLTR);
root.node_.get(), availableWidth, availableHeight, direction);
auto layoutEnd = steady_clock::now();
return BenchmarkResult{

View File

@@ -191,4 +191,16 @@ inline std::string edgeStringFromPropertyName(
std::string propertyName) {
return it.key().substr(propertyName.length() + 1);
}
inline YGDirection directionFromString(std::string str) {
if (str == "ltr") {
return YGDirectionLTR;
} else if (str == "rtl") {
return YGDirectionRTL;
} else if (str == "inherit") {
return YGDirectionInherit;
} else {
throw std::invalid_argument(invalidArgumentMessage(str, "YGDirection"));
}
}
} // namespace facebook::yoga

View File

@@ -9,18 +9,34 @@
#include <capture/CaptureTree.h>
#include <capture/NodeToString.h>
#include <nlohmann/json.hpp>
namespace facebook::yoga {
void captureTree(YGNodeRef node, const std::filesystem::path& path) {
std::string str;
nodeToString(
str,
using namespace nlohmann;
static void captureTree(
std::string_view serializedTree,
const std::filesystem::path& path) {
std::ofstream file(path);
file << serializedTree;
}
void YGNodeCalculateLayoutWithCapture(
YGNodeRef node,
float availableWidth,
float availableHeight,
YGDirection ownerDirection,
const std::filesystem::path& path) {
json j;
serializeLayoutInputs(j, availableWidth, availableHeight, ownerDirection);
serializeTree(
j,
node,
PrintOptions::Style | PrintOptions::Children | PrintOptions::Config |
PrintOptions::Node);
std::ofstream file(path);
file << str;
captureTree(j.dump(2), path);
YGNodeCalculateLayout(node, availableWidth, availableHeight, ownerDirection);
}
} // namespace facebook::yoga

View File

@@ -13,6 +13,11 @@
namespace facebook::yoga {
void captureTree(YGNodeRef node, const std::filesystem::path& path);
void YGNodeCalculateLayoutWithCapture(
YGNodeRef node,
float availableWidth,
float availableHeight,
YGDirection ownerDirection,
const std::filesystem::path& path);
} // namespace facebook::yoga

View File

@@ -8,7 +8,6 @@
#include <memory>
#include <capture/NodeToString.h>
#include <nlohmann/json.hpp>
namespace facebook::yoga {
@@ -121,7 +120,7 @@ YGValue borderFloatToYGValue(YGNodeRef node, YGEdge edge) {
return YGValue{val, unit};
}
static void nodeToStringImpl(json& j, YGNodeRef node, PrintOptions options) {
void serializeTree(json& j, YGNodeRef node, PrintOptions options) {
if ((options & PrintOptions::Layout) == PrintOptions::Layout) {
j["layout"]["width"] = YGNodeStyleGetWidth(node).value;
j["layout"]["height"] = YGNodeStyleGetHeight(node).value;
@@ -303,15 +302,21 @@ static void nodeToStringImpl(json& j, YGNodeRef node, PrintOptions options) {
childCount > 0) {
for (size_t i = 0; i < childCount; i++) {
j["children"].push_back({});
nodeToStringImpl(j["children"][i], YGNodeGetChild(node, i), options);
serializeTree(j["children"][i], YGNodeGetChild(node, i), options);
}
}
}
void nodeToString(std::string& str, YGNodeRef node, PrintOptions options) {
json j;
nodeToStringImpl(j, node, options);
str = j.dump(2);
void serializeLayoutInputs(
json& j,
float availableWidth,
float availableHeight,
YGDirection ownerDirection) {
j["layout-inputs"] = {
{"available-width", availableWidth},
{"available-height", availableHeight},
{"owner-direction", YGDirectionToString(ownerDirection)},
};
}
} // namespace facebook::yoga

View File

@@ -9,6 +9,7 @@
#include <string>
#include <nlohmann/json.hpp>
#include <yoga/Yoga.h>
namespace facebook::yoga {
@@ -22,6 +23,12 @@ enum class PrintOptions : uint8_t {
};
YG_DEFINE_ENUM_FLAG_OPERATORS(PrintOptions);
void nodeToString(std::string& str, YGNodeRef node, PrintOptions options);
void serializeTree(nlohmann::json& j, YGNodeRef root, PrintOptions options);
void serializeLayoutInputs(
nlohmann::json& j,
float availableWidth,
float availableHeight,
YGDirection ownerDirection);
} // namespace facebook::yoga