mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 15:52:55 +01:00
Refactor benchgfx
This commit is contained in:
@@ -320,6 +320,34 @@ static int32_t GetTallestVisibleTileTop(int32_t mapSize, int32_t rotation)
|
||||
return minViewY - 256;
|
||||
}
|
||||
|
||||
static rct_drawpixelinfo CreateDPI(const rct_viewport& viewport)
|
||||
{
|
||||
rct_drawpixelinfo dpi;
|
||||
dpi.width = viewport.width;
|
||||
dpi.height = viewport.height;
|
||||
dpi.bits = new (std::nothrow) uint8_t[dpi.width * dpi.height];
|
||||
if (dpi.bits == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Giant screenshot failed, unable to allocate memory for image.");
|
||||
}
|
||||
|
||||
if (viewport.flags & VIEWPORT_FLAG_TRANSPARENT_BACKGROUND)
|
||||
{
|
||||
std::memset(dpi.bits, PALETTE_INDEX_0, (size_t)dpi.width * dpi.height);
|
||||
}
|
||||
|
||||
return dpi;
|
||||
}
|
||||
|
||||
static void ReleaseDPI(rct_drawpixelinfo& dpi)
|
||||
{
|
||||
if (dpi.bits != nullptr)
|
||||
delete[] dpi.bits;
|
||||
dpi.bits = nullptr;
|
||||
dpi.width = 0;
|
||||
dpi.height = 0;
|
||||
}
|
||||
|
||||
static rct_viewport GetGiantViewport(int32_t mapSize, int32_t rotation, int32_t zoom)
|
||||
{
|
||||
// Get the tile coordinates of each corner
|
||||
@@ -349,25 +377,11 @@ static rct_viewport GetGiantViewport(int32_t mapSize, int32_t rotation, int32_t
|
||||
return viewport;
|
||||
}
|
||||
|
||||
static rct_drawpixelinfo RenderViewport(IDrawingEngine* drawingEngine, const rct_viewport& viewport)
|
||||
static void RenderViewport(IDrawingEngine* drawingEngine, const rct_viewport& viewport, rct_drawpixelinfo& dpi)
|
||||
{
|
||||
// Ensure sprites appear regardless of rotation
|
||||
reset_all_sprite_quadrant_placements();
|
||||
|
||||
rct_drawpixelinfo dpi;
|
||||
dpi.width = viewport.width;
|
||||
dpi.height = viewport.height;
|
||||
dpi.bits = (uint8_t*)malloc((size_t)dpi.width * dpi.height);
|
||||
if (dpi.bits == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Giant screenshot failed, unable to allocate memory for image.");
|
||||
}
|
||||
|
||||
if (viewport.flags & VIEWPORT_FLAG_TRANSPARENT_BACKGROUND)
|
||||
{
|
||||
std::memset(dpi.bits, PALETTE_INDEX_0, (size_t)dpi.width * dpi.height);
|
||||
}
|
||||
|
||||
std::unique_ptr<X8DrawingEngine> tempDrawingEngine;
|
||||
if (drawingEngine == nullptr)
|
||||
{
|
||||
@@ -376,12 +390,11 @@ static rct_drawpixelinfo RenderViewport(IDrawingEngine* drawingEngine, const rct
|
||||
}
|
||||
dpi.DrawingEngine = drawingEngine;
|
||||
viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height);
|
||||
return dpi;
|
||||
}
|
||||
|
||||
void screenshot_giant()
|
||||
{
|
||||
rct_drawpixelinfo dpi;
|
||||
rct_drawpixelinfo dpi{};
|
||||
try
|
||||
{
|
||||
auto path = screenshot_get_next_path();
|
||||
@@ -410,7 +423,9 @@ void screenshot_giant()
|
||||
viewport.flags |= VIEWPORT_FLAG_TRANSPARENT_BACKGROUND;
|
||||
}
|
||||
|
||||
dpi = RenderViewport(nullptr, viewport);
|
||||
dpi = CreateDPI(viewport);
|
||||
|
||||
RenderViewport(nullptr, viewport, dpi);
|
||||
auto renderedPalette = screenshot_get_rendered_palette();
|
||||
WriteDpiToFile(path->c_str(), &dpi, renderedPalette);
|
||||
|
||||
@@ -424,7 +439,17 @@ void screenshot_giant()
|
||||
log_error("%s", e.what());
|
||||
context_show_error(STR_SCREENSHOT_FAILED, STR_NONE);
|
||||
}
|
||||
free(dpi.bits);
|
||||
|
||||
ReleaseDPI(dpi);
|
||||
}
|
||||
|
||||
// TODO: Move this at some point into a more appropriate place.
|
||||
template<typename FN> static inline double MeasureFunctionTime(const FN& fn)
|
||||
{
|
||||
const auto startTime = std::chrono::high_resolution_clock::now();
|
||||
fn();
|
||||
const auto endTime = std::chrono::high_resolution_clock::now();
|
||||
return std::chrono::duration<double>(endTime - startTime).count();
|
||||
}
|
||||
|
||||
static void benchgfx_render_screenshots(const char* inputPath, std::unique_ptr<IContext>& context, uint32_t iterationCount)
|
||||
@@ -437,33 +462,73 @@ static void benchgfx_render_screenshots(const char* inputPath, std::unique_ptr<I
|
||||
gIntroState = INTRO_STATE_NONE;
|
||||
gScreenFlags = SCREEN_FLAGS_PLAYING;
|
||||
|
||||
rct_drawpixelinfo dpi;
|
||||
// Create Viewport and DPI for every rotation and zoom.
|
||||
constexpr int32_t MAX_ROTATIONS = 4;
|
||||
|
||||
std::array<rct_drawpixelinfo, MAX_ROTATIONS * MAX_ZOOM_LEVEL> dpis;
|
||||
std::array<rct_viewport, MAX_ROTATIONS * MAX_ZOOM_LEVEL> viewports;
|
||||
|
||||
for (int32_t zoom = 0; zoom < MAX_ZOOM_LEVEL; zoom++)
|
||||
{
|
||||
for (int32_t rotation = 0; rotation < MAX_ROTATIONS; rotation++)
|
||||
{
|
||||
auto& viewport = viewports[zoom * MAX_ZOOM_LEVEL + rotation];
|
||||
auto& dpi = dpis[zoom * MAX_ZOOM_LEVEL + rotation];
|
||||
viewport = GetGiantViewport(gMapSize, rotation, zoom);
|
||||
dpi = CreateDPI(viewport);
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t totalRenderCount = iterationCount * MAX_ROTATIONS * MAX_ZOOM_LEVEL;
|
||||
|
||||
try
|
||||
{
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
for (uint32_t i = 0; i < iterationCount; i++)
|
||||
{
|
||||
// Render at various zoom levels
|
||||
auto viewport = GetGiantViewport(gMapSize, get_current_rotation(), 0);
|
||||
viewport.zoom = i & 3;
|
||||
dpi = RenderViewport(nullptr, viewport);
|
||||
free(dpi.bits);
|
||||
dpi.bits = nullptr;
|
||||
}
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<float> duration = endTime - startTime;
|
||||
double totalTime = 0.0;
|
||||
|
||||
auto engineStringId = DrawingEngineStringIds[DRAWING_ENGINE_SOFTWARE];
|
||||
auto engineName = format_string(engineStringId, nullptr);
|
||||
std::printf(
|
||||
"Rendering %u times with drawing engine %s took %.2f seconds.", iterationCount, engineName.c_str(),
|
||||
duration.count());
|
||||
std::array<double, MAX_ZOOM_LEVEL> zoomAverages;
|
||||
|
||||
// Render at every zoom.
|
||||
for (int32_t zoom = 0; zoom < MAX_ZOOM_LEVEL; zoom++)
|
||||
{
|
||||
double zoomLevelTime = 0.0;
|
||||
|
||||
// Render at every rotation.
|
||||
for (int32_t rotation = 0; rotation < MAX_ROTATIONS; rotation++)
|
||||
{
|
||||
// N iterations.
|
||||
for (uint32_t i = 0; i < iterationCount; i++)
|
||||
{
|
||||
auto& dpi = dpis[zoom * MAX_ZOOM_LEVEL + rotation];
|
||||
auto& viewport = viewports[zoom * MAX_ZOOM_LEVEL + rotation];
|
||||
double elapsed = MeasureFunctionTime([&viewport, &dpi]() { RenderViewport(nullptr, viewport, dpi); });
|
||||
totalTime += elapsed;
|
||||
zoomLevelTime += elapsed;
|
||||
}
|
||||
}
|
||||
|
||||
zoomAverages[zoom] = zoomLevelTime / static_cast<double>(MAX_ROTATIONS * iterationCount);
|
||||
}
|
||||
|
||||
const double average = totalTime / static_cast<double>(totalRenderCount);
|
||||
const auto engineStringId = DrawingEngineStringIds[DRAWING_ENGINE_SOFTWARE];
|
||||
const auto engineName = format_string(engineStringId, nullptr);
|
||||
std::printf("Engine: %s\n", engineName.c_str());
|
||||
std::printf("Render Count: %u\n", totalRenderCount);
|
||||
for (int32_t zoom = 0; zoom < MAX_ZOOM_LEVEL; zoom++)
|
||||
{
|
||||
const auto zoomAverage = zoomAverages[zoom];
|
||||
std::printf("Zoom[%d] average: %.06fs, %.f FPS\n", zoom, zoomAverage, 1.0 / zoomAverage);
|
||||
}
|
||||
std::printf("Total average: %.06fs, %.f FPS\n", average, 1.0 / average);
|
||||
std::printf("Time: %.05fs\n", totalTime);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::fprintf(stderr, "%s", e.what());
|
||||
}
|
||||
free(dpi.bits);
|
||||
|
||||
for (auto& dpi : dpis)
|
||||
ReleaseDPI(dpi);
|
||||
}
|
||||
|
||||
int32_t cmdline_for_gfxbench(const char** argv, int32_t argc)
|
||||
@@ -475,7 +540,7 @@ int32_t cmdline_for_gfxbench(const char** argv, int32_t argc)
|
||||
}
|
||||
|
||||
core_init();
|
||||
int32_t iterationCount = 40;
|
||||
int32_t iterationCount = 5;
|
||||
if (argc == 2)
|
||||
{
|
||||
iterationCount = atoi(argv[1]);
|
||||
@@ -677,7 +742,9 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption
|
||||
|
||||
ApplyOptions(options, viewport);
|
||||
|
||||
dpi = RenderViewport(nullptr, viewport);
|
||||
dpi = CreateDPI(viewport);
|
||||
|
||||
RenderViewport(nullptr, viewport, dpi);
|
||||
auto renderedPalette = screenshot_get_rendered_palette();
|
||||
WriteDpiToFile(outputPath, &dpi, renderedPalette);
|
||||
}
|
||||
@@ -686,7 +753,8 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption
|
||||
std::printf("%s\n", e.what());
|
||||
exitCode = -1;
|
||||
}
|
||||
free(dpi.bits);
|
||||
ReleaseDPI(dpi);
|
||||
|
||||
drawing_engine_dispose();
|
||||
|
||||
return exitCode;
|
||||
|
||||
Reference in New Issue
Block a user