diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index f9a5ecb195..451e486381 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -84,7 +84,7 @@ if (NOT DISABLE_TTF) endif () if (NOT DISABLE_GOOGLE_BENCHMARK) - find_package(benchmark 1.4 QUIET) + find_package(benchmark) if (benchmark_FOUND) message("Found Google benchmark, enabling support") set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS USE_BENCHMARK) diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index f9390803ec..e11f9049ec 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -827,9 +827,33 @@ void viewport_render( #endif } -static void viewport_fill_column(paint_session* session) +static void record_session(const paint_session* session, std::vector* recorded_sessions, size_t record_index) +{ + // Perform a deep copy of the paint session, use relative offsets. + // This is done to extract the session for benchmark. + // Place the copied session at provided record_index, so the caller can decide which columns/paint sessions to copy; there + // is no column information embedded in the session itself. + (*recorded_sessions)[record_index] = (*session); + paint_session* session_copy = &recorded_sessions->at(record_index); + + // Mind the offset needs to be calculated against the original `session`, not `session_copy` + for (auto& ps : session_copy->PaintStructs) + { + ps.basic.next_quadrant_ps = (paint_struct*)(ps.basic.next_quadrant_ps ? int(ps.basic.next_quadrant_ps - &session->PaintStructs[0].basic) : std::size(session->PaintStructs)); + } + for (auto& quad : session_copy->Quadrants) + { + quad = (paint_struct*)(quad ? int(quad - &session->PaintStructs[0].basic) : std::size(session->Quadrants)); + } +} + +static void viewport_fill_column(paint_session* session, std::vector* recorded_sessions, size_t record_index) { paint_session_generate(session); + if (recorded_sessions != nullptr) + { + record_session(session, recorded_sessions, record_index); + } paint_session_arrange(session); } @@ -876,7 +900,7 @@ static void viewport_paint_column(paint_session* session) */ void viewport_paint( const rct_viewport* viewport, rct_drawpixelinfo* dpi, int16_t left, int16_t top, int16_t right, int16_t bottom, - std::vector* sessions) + std::vector* recorded_sessions) { uint32_t viewFlags = viewport->flags; uint16_t width = right - left; @@ -926,8 +950,15 @@ void viewport_paint( _paintJobs.reset(); } - // Splits the area into 32 pixel columns and renders them + // Create space to record sessions and keep track which index is being drawn size_t index = 0; + if (recorded_sessions != nullptr) + { + const uint16_t column_count = (rightBorder - floor2(dpi1.x, 32)) / 32 + 1; + recorded_sessions->resize(column_count); + } + + // Splits the area into 32 pixel columns and renders them for (x = floor2(dpi1.x, 32); x < rightBorder; x += 32, index++) { paint_session* session = paint_session_alloc(&dpi1, viewFlags); @@ -954,11 +985,12 @@ void viewport_paint( if (useMultithreading) { - _paintJobs->AddTask([session]() -> void { viewport_fill_column(session); }); + _paintJobs->AddTask( + [session, recorded_sessions, index]() -> void { viewport_fill_column(session, recorded_sessions, index); }); } else { - viewport_fill_column(session); + viewport_fill_column(session, recorded_sessions, index); } }