mirror of
				https://github.com/RetroDECK/ES-DE.git
				synced 2025-04-10 19:15:13 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			161 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #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;
 | |
| }
 | 
