From 990a153b8206a7d05900303dc07f823190dab2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 18 Jun 2017 23:17:37 +0200 Subject: [PATCH 1/2] Add support for benchmarking park rendering --- src/openrct2/cmdline/BenchGfxCommmands.cpp | 38 +++++++++ src/openrct2/cmdline/CommandLine.hpp | 1 + src/openrct2/cmdline/RootCommands.cpp | 1 + src/openrct2/interface/Screenshot.cpp | 93 ++++++++++++++++++++++ src/openrct2/interface/Screenshot.h | 1 + 5 files changed, 134 insertions(+) create mode 100644 src/openrct2/cmdline/BenchGfxCommmands.cpp diff --git a/src/openrct2/cmdline/BenchGfxCommmands.cpp b/src/openrct2/cmdline/BenchGfxCommmands.cpp new file mode 100644 index 0000000000..ec4bb54cb7 --- /dev/null +++ b/src/openrct2/cmdline/BenchGfxCommmands.cpp @@ -0,0 +1,38 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + +#include "../interface/Screenshot.h" +#include "CommandLine.hpp" + +static exitcode_t HandleBenchGfx(CommandLineArgEnumerator *argEnumerator); + +const CommandLineCommand CommandLine::BenchGfxCommands[] +{ + // Main commands + DefineCommand("", " [iterations count]", nullptr, HandleBenchGfx), + CommandTableEnd +}; + +static exitcode_t HandleBenchGfx(CommandLineArgEnumerator *argEnumerator) +{ + const char * * argv = (const char * *)argEnumerator->GetArguments() + argEnumerator->GetIndex(); + sint32 argc = argEnumerator->GetCount() - argEnumerator->GetIndex(); + sint32 result = cmdline_for_gfxbench(argv, argc); + if (result < 0) { + return EXITCODE_FAIL; + } + return EXITCODE_OK; +} diff --git a/src/openrct2/cmdline/CommandLine.hpp b/src/openrct2/cmdline/CommandLine.hpp index d267462532..51620f640a 100644 --- a/src/openrct2/cmdline/CommandLine.hpp +++ b/src/openrct2/cmdline/CommandLine.hpp @@ -103,6 +103,7 @@ namespace CommandLine extern const CommandLineCommand RootCommands[]; extern const CommandLineCommand ScreenshotCommands[]; extern const CommandLineCommand SpriteCommands[]; + extern const CommandLineCommand BenchGfxCommands[]; extern const CommandLineExample RootExamples[]; diff --git a/src/openrct2/cmdline/RootCommands.cpp b/src/openrct2/cmdline/RootCommands.cpp index e1a828686b..e0f01c5382 100644 --- a/src/openrct2/cmdline/RootCommands.cpp +++ b/src/openrct2/cmdline/RootCommands.cpp @@ -138,6 +138,7 @@ const CommandLineCommand CommandLine::RootCommands[] // Sub-commands DefineSubCommand("screenshot", CommandLine::ScreenshotCommands), DefineSubCommand("sprite", CommandLine::SpriteCommands ), + DefineSubCommand("benchgfx", CommandLine::BenchGfxCommands ), CommandTableEnd }; diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index a6db3913b5..df7e6260db 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -14,9 +14,11 @@ *****************************************************************************/ #pragma endregion +#include #include "../audio/audio.h" #include "../config/Config.h" #include "../Context.h" +#include "../core/Console.hpp" #include "../Imaging.h" #include "../OpenRCT2.h" #include "Screenshot.h" @@ -245,6 +247,97 @@ void screenshot_giant() window_error_open(STR_SCREENSHOT_SAVED_AS, STR_NONE); } +sint32 cmdline_for_gfxbench(const char **argv, sint32 argc) +{ + if (argc != 1 && argc != 2) { + printf("Usage: openrct2 benchgfx []\n"); + return -1; + } + + sint32 iteration_count = 40; + if (argc == 2) + { + iteration_count = atoi(argv[1]); + } + + sint32 resolutionWidth, resolutionHeight, customX = 0, customY = 0; + + const char *inputPath = argv[0]; + + gOpenRCT2Headless = true; + auto context = CreateContext(); + if (context->Initialise()) + { + drawing_engine_init(); + rct2_open_file(inputPath); + + gIntroState = INTRO_STATE_NONE; + gScreenFlags = SCREEN_FLAGS_PLAYING; + + sint32 mapSize = gMapSize; + resolutionWidth = (mapSize * 32 * 2); + resolutionHeight = (mapSize * 32 * 1); + + resolutionWidth += 8; + resolutionHeight += 128; + + rct_viewport viewport; + viewport.x = 0; + viewport.y = 0; + viewport.width = resolutionWidth; + viewport.height = resolutionHeight; + viewport.view_width = viewport.width; + viewport.view_height = viewport.height; + viewport.var_11 = 0; + viewport.flags = 0; + + customX = (mapSize / 2) * 32 + 16; + customY = (mapSize / 2) * 32 + 16; + + sint32 x = 0, y = 0; + sint32 z = map_element_height(customX, customY) & 0xFFFF; + x = customY - customX; + y = ((customX + customY) / 2) - z; + + viewport.view_x = x - ((viewport.view_width) / 2); + viewport.view_y = y - ((viewport.view_height) / 2); + viewport.zoom = 0; + gCurrentRotation = 0; + + // Ensure sprites appear regardless of rotation + reset_all_sprite_quadrant_placements(); + + rct_drawpixelinfo dpi; + dpi.x = 0; + dpi.y = 0; + dpi.width = resolutionWidth; + dpi.height = resolutionHeight; + dpi.pitch = 0; + dpi.bits = (uint8 *)malloc(dpi.width * dpi.height); + + auto startTime = std::chrono::high_resolution_clock::now(); + for (sint32 i = 0; i < iteration_count; i++) + { + // Render at various zoom levels + dpi.zoom_level = i & 3; + viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); + } + auto endTime = std::chrono::high_resolution_clock::now(); + std::chrono::duration duration = endTime - startTime; + char engine_name[128]; + rct_string_id engine_id = DrawingEngineStringIds[drawing_engine_get_type()]; + format_string(engine_name, sizeof(engine_name), engine_id, nullptr); + Console::WriteLine("Rendering %d times with drawing engine %s took %.2f seconds.", + iteration_count, engine_name, + duration.count()); + + free(dpi.bits); + drawing_engine_dispose(); + } + delete context; + return 1; +} + sint32 cmdline_for_screenshot(const char **argv, sint32 argc) { bool giantScreenshot = argc == 5 && _stricmp(argv[2], "giant") == 0; diff --git a/src/openrct2/interface/Screenshot.h b/src/openrct2/interface/Screenshot.h index a4c9b8dcb6..02f7d9cf96 100644 --- a/src/openrct2/interface/Screenshot.h +++ b/src/openrct2/interface/Screenshot.h @@ -31,6 +31,7 @@ extern "C" void screenshot_giant(); sint32 cmdline_for_screenshot(const char **argv, sint32 argc); + sint32 cmdline_for_gfxbench(const char **argv, sint32 argc); #ifdef __cplusplus } #endif From e9e2b79f1c48dc79da09143fe4bb0c48f18019b9 Mon Sep 17 00:00:00 2001 From: LRFLEW Date: Sun, 18 Jun 2017 23:43:27 -0500 Subject: [PATCH 2/2] Update Xcode Project --- OpenRCT2.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 89c808c262..271ae56cfa 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -73,6 +73,7 @@ D45A395E1CF300AF00659A24 /* libSDL2.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B81CF3006400659A24 /* libSDL2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D45A395F1CF300AF00659A24 /* libspeexdsp.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B91CF3006400659A24 /* libspeexdsp.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D47304D51C4FF8250015C0EA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D47304D41C4FF8250015C0EA /* libz.tbd */; }; + D48AFDB71EF78DBF0081C644 /* BenchGfxCommmands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D48AFDB61EF78DBF0081C644 /* BenchGfxCommmands.cpp */; }; D4A8B4B41DB41873007A2F29 /* libpng16.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A8B4B31DB41873007A2F29 /* libpng16.dylib */; }; D4A8B4B51DB4188D007A2F29 /* libpng16.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D4A8B4B31DB41873007A2F29 /* libpng16.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D4EC48E61C2637710024B507 /* g2.dat in Resources */ = {isa = PBXBuildFile; fileRef = D4EC48E31C2637710024B507 /* g2.dat */; }; @@ -772,6 +773,7 @@ D45A39581CF3007A00659A24 /* speexdsp_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = speexdsp_types.h; sourceTree = ""; }; D47304D41C4FF8250015C0EA /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; D4895D321C23EFDD000CD788 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = distribution/macos/Info.plist; sourceTree = SOURCE_ROOT; }; + D48AFDB61EF78DBF0081C644 /* BenchGfxCommmands.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BenchGfxCommmands.cpp; sourceTree = ""; }; D497D0781C20FD52002BF46A /* OpenRCT2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OpenRCT2.app; sourceTree = BUILT_PRODUCTS_DIR; }; D4A8B4B31DB41873007A2F29 /* libpng16.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libpng16.dylib; sourceTree = ""; }; D4EC48E31C2637710024B507 /* g2.dat */ = {isa = PBXFileReference; lastKnownFileType = file; name = g2.dat; path = data/g2.dat; sourceTree = SOURCE_ROOT; }; @@ -1805,6 +1807,7 @@ F76C83621EC4E7CC00FA49E2 /* cmdline */ = { isa = PBXGroup; children = ( + D48AFDB61EF78DBF0081C644 /* BenchGfxCommmands.cpp */, F76C83631EC4E7CC00FA49E2 /* CommandLine.cpp */, F76C83641EC4E7CC00FA49E2 /* CommandLine.hpp */, F76C83651EC4E7CC00FA49E2 /* ConvertCommand.cpp */, @@ -3030,6 +3033,7 @@ F76C85D41EC4E88300FA49E2 /* File.cpp in Sources */, F76C85D61EC4E88300FA49E2 /* FileScanner.cpp in Sources */, F76C85D91EC4E88300FA49E2 /* Guard.cpp in Sources */, + D48AFDB71EF78DBF0081C644 /* BenchGfxCommmands.cpp in Sources */, F76C85DB1EC4E88300FA49E2 /* IStream.cpp in Sources */, F76C85DD1EC4E88300FA49E2 /* Json.cpp in Sources */, F76C85E11EC4E88300FA49E2 /* MemoryStream.cpp in Sources */,