forked from Samsung/rlottie
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlottieperf.cpp
160 lines (147 loc) · 4.82 KB
/
lottieperf.cpp
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
#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;
}