You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
4.8 KiB
160 lines
4.8 KiB
#include <memory> |
|
#include <vector> |
|
#include <dirent.h> |
|
#include <algorithm> |
|
#include <chrono> |
|
#include <iostream> |
|
#include <cstring> |
|
|
|
#include <rlottie.h> |
|
|
|
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<std::string> |
|
jsonFiles(const std::string &dirName) |
|
{ |
|
DIR *d; |
|
struct dirent *dir; |
|
std::vector<std::string> 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<uint32_t[]>(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<uint32_t[]> _buffer; |
|
std::unique_ptr<rlottie::Animation> _animation; |
|
size_t _frames{0}; |
|
size_t _cur{0}; |
|
rlottie::Surface _surface; |
|
std::future<rlottie::Surface> _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<double> secs = std::chrono::high_resolution_clock::now() - start; |
|
std::chrono::duration<double, std::milli> 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<Renderer>(_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<std::string> _resourceList; |
|
std::vector<std::unique_ptr<Renderer>> _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; |
|
}
|
|
|