From 1105ff5b814a7c6bfffcab52a4a53e44f1ec166d Mon Sep 17 00:00:00 2001 From: "sub.mohanty@samsung.com" Date: Mon, 17 Aug 2020 16:11:47 +0900 Subject: [PATCH] example: added a perf test to keep track of performance --- example/lottieperf.cpp | 160 +++++++++++++++++++++++++++++++++++++++++ example/meson.build | 10 +++ 2 files changed, 170 insertions(+) create mode 100644 example/lottieperf.cpp diff --git a/example/lottieperf.cpp b/example/lottieperf.cpp new file mode 100644 index 0000000..f1b6cb0 --- /dev/null +++ b/example/lottieperf.cpp @@ -0,0 +1,160 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +static bool isJsonFile(const char *filename) { + const char *dot = strrchr(filename, '.'); + if(!dot || dot == filename) return false; + return !strcmp(dot + 1, "json"); +} + +static std::vector +jsonFiles(const std::string &dirName) +{ + DIR *d; + struct dirent *dir; + std::vector result; + d = opendir(dirName.c_str()); + if (d) { + while ((dir = readdir(d)) != NULL) { + if (isJsonFile(dir->d_name)) + result.push_back(dirName + dir->d_name); + } + closedir(d); + } + + std::sort(result.begin(), result.end(), [](auto & a, auto &b){return a < b;}); + + return result; +} + +class Renderer +{ +public: + explicit Renderer(const std::string& filename) + { + _animation = rlottie::Animation::loadFromFile(filename); + _frames = _animation->totalFrame(); + _buffer = std::make_unique(100 * 100); + _surface = rlottie::Surface(_buffer.get(), 100, 100, 100 * 4); + } + void render() + { + if (_cur >= _frames) _cur = 0; + _animation->renderSync(_cur++, _surface); + } + void renderAsync() + { + if (_cur >= _frames) _cur = 0; + _future = _animation->render(_cur++, _surface); + } + void get() + { + if (_future.valid()) _future.get(); + } +private: + std::unique_ptr _buffer; + std::unique_ptr _animation; + size_t _frames{0}; + size_t _cur{0}; + rlottie::Surface _surface; + std::future _future; +}; + +class PerfTest +{ +public: + explicit PerfTest(size_t resourceCount, size_t iterations): + _resourceCount(resourceCount), _iterations(iterations) + { + _resourceList = jsonFiles(std::string(DEMO_DIR)); + } + void test(bool async) + { + setup(); + std::cout<<" Test Started : .... \n"; + auto start = std::chrono::high_resolution_clock::now(); + benchmark(async); + std::chrono::duration secs = std::chrono::high_resolution_clock::now() - start; + std::chrono::duration millisecs = secs; + std::cout<< " Test Finished.\n"; + std::cout<< " \nPerformance Report: \n\n"; + std::cout<< " \t Resource Rendered per Frame : "<< _resourceCount <<"\n"; + std::cout<< " \t Render Buffer Size : (100 X 100) \n"; + std::cout<< " \t Render Mode : "<< (async ? "Async" : "Sync")<<"\n"; + std::cout<< " \t Total Frames Rendered : "<< _iterations<<"\n"; + std::cout<< " \t Total Render Time : "<< secs.count()<<"sec\n"; + std::cout<< " \t Avrage Time per Resource : "<< millisecs.count() / (_iterations * _resourceCount)<<"ms\n"; + std::cout<< " \t Avrage Time Per Frame : "<< millisecs.count() / _iterations <<"ms\n"; + std::cout<< " \t FPS : "<< _iterations / secs.count() <<"fps\n\n"; + } +private: + void setup() + { + for (auto i = 0u; i < _resourceCount; i++) { + auto index = i % _resourceList.size(); + _renderers.push_back(std::make_unique(_resourceList[index])); + } + } + + void benchmark(bool async) + { + for (auto i = 0u; i < _iterations; i++) { + if (async) { + for (const auto &e : _renderers) e->renderAsync(); + for (const auto &e : _renderers) e->get(); + } else { + for (const auto &e : _renderers) e->render(); + } + } + } + +private: + size_t _resourceCount; + size_t _iterations; + + std::vector _resourceList; + std::vector> _renderers; +}; + +static int help() +{ + std::cout<<"\nUsage : ./perf [--sync] [-c] [resource count] [-i] [iteration count] \n"; + std::cout<<"\nExample : ./perf -c 50 -i 100 \n"; + std::cout<<"\n\t runs perf test for 100 iterations. renders 50 resource per iteration\n\n"; + return 0; +} +int +main(int argc, char ** argv) +{ + bool async = true; + size_t resourceCount = 250; + size_t iterations = 500; + auto index = 0; + + while (index < argc) { + const char* option = argv[index]; + index++; + if (!strcmp(option,"--help") || !strcmp(option,"-h")) { + return help(); + } else if (!strcmp(option,"--sync")) { + async = false; + } else if (!strcmp(option,"-c")) { + resourceCount = (index < argc) ? atoi(argv[index]) : resourceCount; + index++; + } else if (!strcmp(option,"-i")) { + iterations = (index < argc) ? atoi(argv[index]) : iterations; + index++; + } + } + + PerfTest obj(resourceCount, iterations); + obj.test(async); + return 0; +} diff --git a/example/meson.build b/example/meson.build index 8a47413..f5b864b 100644 --- a/example/meson.build +++ b/example/meson.build @@ -13,6 +13,14 @@ executable('lottie2gif', override_options : override_default, link_with : rlottie_lib) +if host_machine.system() != 'windows' + executable('perf', + 'lottieperf.cpp', + include_directories : inc, + override_options : override_default, + link_with : rlottie_lib) +endif + demo_dep = dependency('elementary', required : false, disabler : true) executable('demo', @@ -62,3 +70,5 @@ executable('lottieviewer', override_options : override_default, link_with : rlottie_lib, dependencies : demo_dep) + + -- 2.34.1