1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2 
3 #include <map>
4 #include <stdio.h>
5 #include "Benchmark.h"
6 
7 #include "Game.h"
8 #include "GlobalUnsynced.h"
9 #include "UI/GuiHandler.h"
10 #include "Rendering/GlobalRendering.h"
11 #include "Sim/Units/UnitHandler.h"
12 #include "Sim/Features/FeatureHandler.h"
13 #include "System/TimeProfiler.h"
14 
15 static std::map<float, float> realFPS;
16 static std::map<float, float> drawFPS;
17 static std::map<int, float>   simFPS;
18 static std::map<int, size_t>  units;
19 static std::map<int, size_t>  features;
20 static std::map<int, float>   gameSpeed;
21 static std::map<int, float>   luaUsage;
22 
23 bool CBenchmark::enabled = false;
24 int CBenchmark::startFrame = 0;
25 int CBenchmark::endFrame = 5 * 60 * GAME_SPEED;
26 
27 
CBenchmark()28 CBenchmark::CBenchmark()
29 	: CEventClient("[CBenchmark]", 271990, false)
30 {
31 	eventHandler.AddClient(this);
32 }
33 
~CBenchmark()34 CBenchmark::~CBenchmark()
35 {
36 	FILE* pFile = fopen("benchmark.data", "w");
37 	std::map<float, float>::const_iterator rit = realFPS.begin();
38 	std::map<float, float>::const_iterator dit = drawFPS.begin();
39 	std::map<int, float>::const_iterator   sit = simFPS.begin();
40 	std::map<int, size_t>::const_iterator  uit = units.begin();
41 	std::map<int, size_t>::const_iterator  fit = features.begin();
42 	std::map<int, float>::const_iterator   git = gameSpeed.begin();
43 	std::map<int, float>::const_iterator   lit = luaUsage.begin();
44 
45 	fprintf(pFile, "# GAME_FRAME effFPS drawFPS simFPS num_units num_features game_speed lua_usage\n");
46 	while (dit != drawFPS.end() && sit != simFPS.end())
47 	{
48 		if (dit->first < sit->first) {
49 			fprintf(pFile, "%f %f %f %f " _STPF_ " " _STPF_ " %f %f\n", dit->first, rit->second, dit->second, sit->second, uit->second, fit->second, git->second, lit->second);
50 			++dit;
51 			++rit;
52 		} else {
53 			fprintf(pFile, "%f %f %f %f " _STPF_ " " _STPF_ " %f %f\n", (float)sit->first, rit->second, dit->second, sit->second, uit->second, fit->second, git->second, lit->second);
54 			++sit;
55 			++uit;
56 			++fit;
57 			++git;
58 			++lit;
59 		}
60 	}
61 	fclose(pFile);
62 }
63 
GameFrame(int gameFrame)64 void CBenchmark::GameFrame(int gameFrame)
65 {
66 	if (gameFrame == 0 && (startFrame - 45 * GAME_SPEED > 0)) {
67 		std::vector<string> cmds;
68 		cmds.push_back("@@setmaxspeed 100");
69 		cmds.push_back("@@setminspeed 100");
70 		guihandler->RunCustomCommands(cmds, false);
71 	}
72 
73 	if (gameFrame == (startFrame - 45 * GAME_SPEED)) {
74 		std::vector<string> cmds;
75 		cmds.push_back("@@setminspeed 1");
76 		cmds.push_back("@@setmaxspeed 1");
77 		guihandler->RunCustomCommands(cmds, false);
78 	}
79 
80 	if (gameFrame >= startFrame) {
81 		simFPS[gameFrame] = (gu->avgSimFrameTime == 0.0f)? 0.0f: 1000.0f / gu->avgSimFrameTime;
82 		units[gameFrame] = unitHandler->units.size();
83 		features[gameFrame] = featureHandler->GetActiveFeatures().size();
84 		gameSpeed[gameFrame] = GAME_SPEED * gs->wantedSpeedFactor;
85 		luaUsage[gameFrame] = profiler.GetPercent("Lua");
86 	}
87 
88 	if (gameFrame == endFrame) {
89 		gu->globalQuit = true;
90 	}
91 }
92 
DrawWorld()93 void CBenchmark::DrawWorld()
94 {
95 	if (!simFPS.empty()) {
96 		realFPS[game->lastSimFrame + globalRendering->timeOffset] = globalRendering->FPS;
97 		drawFPS[game->lastSimFrame + globalRendering->timeOffset] = (gu->avgDrawFrameTime == 0.0f)? 0.0f: 1000.0f / gu->avgDrawFrameTime;
98 	}
99 }
100