all repos — mgba @ 6ca25e44aa55b8930d14ad313fa1ad5c94c4f8bf

mGBA Game Boy Advance Emulator

src/platform/perf-main.c (view raw)

 1#include "gba-thread.h"
 2#include "gba.h"
 3#include "renderers/video-software.h"
 4
 5#include <fcntl.h>
 6#include <signal.h>
 7#include <sys/time.h>
 8
 9static void _GBAPerfRunloop(struct GBAThread* context, int* frames);
10static void _GBAPerfShutdown(int signal);
11
12static struct GBAThread* _thread;
13
14int main(int argc, char** argv) {
15	signal(SIGINT, _GBAPerfShutdown);
16
17	struct GBAVideoSoftwareRenderer renderer;
18	GBAVideoSoftwareRendererCreate(&renderer);
19
20	struct StartupOptions opts;
21	if (!parseCommandArgs(&opts, argc, argv, PERF_OPTIONS)) {
22		usage(argv[0], PERF_USAGE);
23		return 1;
24	}
25
26	renderer.outputBuffer = malloc(256 * 256 * 4);
27	renderer.outputBufferStride = 256;
28
29	struct GBAThread context = {
30		.renderer = &renderer.d,
31		.sync.videoFrameWait = 0,
32		.sync.audioWait = 0
33	};
34	_thread = &context;
35
36	context.debugger = createDebugger(&opts);
37
38	GBAMapOptionsToContext(&opts, &context);
39
40	GBAThreadStart(&context);
41
42	int frames = opts.perfDuration;
43	time_t start = time(0);
44	_GBAPerfRunloop(&context, &frames);
45	time_t end = time(0);
46	int duration = end - start;
47
48	GBAThreadJoin(&context);
49	close(opts.fd);
50	if (opts.biosFd >= 0) {
51		close(opts.biosFd);
52	}
53	free(context.debugger);
54
55	free(renderer.outputBuffer);
56
57	printf("%u frames in %i seconds: %g fps (%gx)\n", frames, duration, frames / (float) duration, frames / (duration * 60.f));
58
59	return 0;
60}
61
62static void _GBAPerfRunloop(struct GBAThread* context, int* frames) {
63	struct timeval lastEcho;
64	gettimeofday(&lastEcho, 0);
65	int duration = *frames;
66	*frames = 0;
67	int lastFrames = 0;
68	while (context->state < THREAD_EXITING) {
69		if (GBASyncWaitFrameStart(&context->sync, 0)) {
70			++*frames;
71			++lastFrames;
72			struct timeval currentTime;
73			long timeDiff;
74			gettimeofday(&currentTime, 0);
75			timeDiff = currentTime.tv_sec - lastEcho.tv_sec;
76			timeDiff *= 1000;
77			timeDiff += (currentTime.tv_usec - lastEcho.tv_usec) / 1000;
78			if (timeDiff >= 1000) {
79				printf("\033[2K\rCurrent FPS: %g (%gx)", lastFrames / (timeDiff / 1000.0f), lastFrames / (float) (60 * (timeDiff / 1000.0f)));
80				fflush(stdout);
81				lastEcho = currentTime;
82				lastFrames = 0;
83			}
84		}
85		GBASyncWaitFrameEnd(&context->sync);
86		if (*frames == duration * 60) {
87			_GBAPerfShutdown(0);
88		}
89	}
90	printf("\033[2K\r");
91}
92
93static void _GBAPerfShutdown(int signal) {
94	(void) (signal);
95	pthread_mutex_lock(&_thread->stateMutex);
96	_thread->state = THREAD_EXITING;
97	pthread_mutex_unlock(&_thread->stateMutex);
98}