From bba967d62e051c0e291219a0f2dec7f5d8c4efd3 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 2 May 2021 22:02:09 +0100 Subject: [PATCH] Start working on benchmark changes --- src/openrct2/interface/Viewport.cpp | 66 ++++++++++++++++++++++------- src/openrct2/interface/Viewport.h | 5 ++- src/openrct2/paint/Paint.cpp | 12 ++++++ src/openrct2/paint/Paint.h | 17 ++++++-- 4 files changed, 80 insertions(+), 20 deletions(-) diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index b4b46a1b8d..f946022a2a 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -805,7 +805,7 @@ void viewport_update_smart_vehicle_follow(rct_window* window) */ void viewport_render( rct_drawpixelinfo* dpi, const rct_viewport* viewport, int32_t left, int32_t top, int32_t right, int32_t bottom, - std::vector* sessions) + std::vector* sessions) { if (right <= viewport->pos.x) return; @@ -846,32 +846,68 @@ void viewport_render( #endif } -static void record_session(const paint_session* session, std::vector* recorded_sessions, size_t record_index) +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); + auto& recordedSession = recorded_sessions->at(record_index); + recordedSession.Session = *session; + recordedSession.Entries.resize(session->PaintEntryChain.GetCount()); // Mind the offset needs to be calculated against the original `session`, not `session_copy` - for (auto& ps : session_copy->PaintStructs) + std::unordered_map entryRemap; + + // Copy all entries + auto paintIndex = 0; + auto chain = session->PaintEntryChain.Head; + while (chain != nullptr) { - ps.basic.next_quadrant_ps = reinterpret_cast( - ps.basic.next_quadrant_ps ? int(ps.basic.next_quadrant_ps - &session->PaintStructs[0].basic) - : std::size(session->PaintStructs)); + for (size_t i = 0; i < chain->Count; i++) + { + auto& src = chain->PaintStructs[i]; + auto& dst = recordedSession.Entries[paintIndex++]; + dst = src; + entryRemap[&src.basic] = reinterpret_cast(i * sizeof(paint_entry)); + } + chain = chain->Next; } - for (auto& quad : session_copy->Quadrants) + entryRemap[nullptr] = reinterpret_cast(-1); + + // Remap all entries + for (auto& ps : recordedSession.Entries) { - quad = reinterpret_cast( - quad ? int(quad - &session->PaintStructs[0].basic) : std::size(session->Quadrants)); + auto& ptr = ps.basic.next_quadrant_ps; + auto it = entryRemap.find(ptr); + if (it == entryRemap.end()) + { + assert(false); + ptr = nullptr; + } + else + { + ptr = it->second; + } + } + for (auto& ptr : recordedSession.Session.Quadrants) + { + auto it = entryRemap.find(ptr); + if (it == entryRemap.end()) + { + assert(false); + ptr = nullptr; + } + else + { + ptr = it->second; + } } - */ } -static void viewport_fill_column(paint_session* session, std::vector* recorded_sessions, size_t record_index) +static void viewport_fill_column( + paint_session* session, std::vector* recorded_sessions, size_t record_index) { PaintSessionGenerate(session); if (recorded_sessions != nullptr) @@ -924,7 +960,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* recorded_sessions) + std::vector* recorded_sessions) { uint32_t viewFlags = viewport->flags; uint16_t width = right - left; diff --git a/src/openrct2/interface/Viewport.h b/src/openrct2/interface/Viewport.h index d62da72b0c..cc4750ab6a 100644 --- a/src/openrct2/interface/Viewport.h +++ b/src/openrct2/interface/Viewport.h @@ -18,6 +18,7 @@ #include struct paint_session; +struct RecordedPaintSession; struct paint_struct; struct rct_drawpixelinfo; struct Peep; @@ -116,10 +117,10 @@ void viewport_update_smart_staff_follow(rct_window* window, Peep* peep); void viewport_update_smart_vehicle_follow(rct_window* window); void viewport_render( rct_drawpixelinfo* dpi, const rct_viewport* viewport, int32_t left, int32_t top, int32_t right, int32_t bottom, - std::vector* sessions = nullptr); + std::vector* sessions = nullptr); 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 = nullptr); + std::vector* sessions = nullptr); CoordsXYZ viewport_adjust_for_map_height(const ScreenCoordsXY& startCoords); diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index b000725ad9..3251cde1b6 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -1041,6 +1041,18 @@ void PaintEntryPool::Chain::Clear() assert(Current == nullptr); } +size_t PaintEntryPool::Chain::GetCount() const +{ + size_t count = 0; + auto current = Head; + while (current != nullptr) + { + count += current->Count; + current = current->Next; + } + return count; +} + PaintEntryPool::~PaintEntryPool() { for (auto node : _available) diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index 5360209c4b..328311dbc5 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -172,6 +172,7 @@ public: paint_entry* Allocate(); void Clear(); + size_t GetCount() const; }; private: @@ -187,10 +188,8 @@ public: void FreeNodes(Node* head); }; -struct paint_session +struct PaintSessionCore { - rct_drawpixelinfo DPI; - PaintEntryPool::Chain PaintEntryChain; paint_struct* Quadrants[MAX_PAINT_QUADRANTS]; paint_struct* LastPS; paint_string_struct* PSStringHead; @@ -220,6 +219,12 @@ struct paint_session uint8_t Unk141E9DB; uint16_t WaterHeight; uint32_t TrackColours[4]; +}; + +struct paint_session : public PaintSessionCore +{ + rct_drawpixelinfo DPI; + PaintEntryPool::Chain PaintEntryChain; paint_struct* AllocateNormalPaintEntry() noexcept { @@ -264,6 +269,12 @@ struct paint_session } }; +struct RecordedPaintSession +{ + PaintSessionCore Session; + std::vector Entries; +}; + extern paint_session gPaintSession; // Globals for paint clipping