From 3fecb36a196ecf876dc0b0f4d1b602fe4e7e0f1c Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 30 Jan 2021 08:10:40 +0200 Subject: [PATCH 1/2] Use fixed vector for paint_entry --- src/openrct2/core/FixedVector.h | 44 ++++++++++++++++----------------- src/openrct2/paint/Paint.h | 21 +++++++--------- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/openrct2/core/FixedVector.h b/src/openrct2/core/FixedVector.h index f4e5908c44..ff53dee133 100644 --- a/src/openrct2/core/FixedVector.h +++ b/src/openrct2/core/FixedVector.h @@ -27,7 +27,7 @@ public: using reference_type = value_type&; using const_reference_type = const value_type&; - iterator begin() + constexpr iterator begin() { if (_count == 0) return _data.end(); @@ -35,14 +35,14 @@ public: return _data.begin(); } - iterator end() + constexpr iterator end() { if (_count == 0) return _data.end(); return begin() + _count; } - const_iterator cbegin() const + constexpr const_iterator cbegin() const { if (_count == 0) return _data.cend(); @@ -50,58 +50,58 @@ public: return _data.cbegin(); } - const_iterator cend() const + constexpr const_iterator cend() const { if (_count == 0) return _data.cend(); return cbegin() + _count; } - reverse_iterator rbegin() + constexpr reverse_iterator rbegin() { if (_count == 0) return _data.rend(); return _data.rbegin() + (MAX - _count); } - reverse_iterator rend() + constexpr reverse_iterator rend() { return _data.rend(); } - const_reverse_iterator rbegin() const + constexpr const_reverse_iterator rbegin() const { return _data.rbegin() + (MAX - _count); } - const_reverse_iterator rend() const + constexpr const_reverse_iterator rend() const { return _data.rend(); } - reference_type back() + constexpr reference_type back() { return _data[_count - 1]; } - const_reference_type back() const + constexpr const_reference_type back() const { return _data[_count - 1]; } - void push_back(const T& val) + constexpr void push_back(const T& val) { Guard::Assert(_count < MAX); _data[_count++] = val; } - void push_back(T&& val) + constexpr void push_back(T&& val) { Guard::Assert(_count < MAX); _data[_count++] = std::move(val); } - iterator insert(iterator pos, const T& val) + constexpr iterator insert(iterator pos, const T& val) { // Make sure the end iterator is correct. auto itCurEnd = end(); @@ -114,7 +114,7 @@ public: return _data.begin() + offset; } - iterator insert(iterator pos, T&& val) + constexpr iterator insert(iterator pos, T&& val) { // Make sure the end iterator is correct. auto itCurEnd = end(); @@ -127,7 +127,7 @@ public: return _data.begin() + offset; } - template reference_type emplace_back(Args&&... args) + template constexpr reference_type emplace_back(Args&&... args) { Guard::Assert(_count < MAX); reference_type res = _data[_count++]; @@ -135,37 +135,37 @@ public: return res; } - reference_type operator[](const size_t n) + constexpr reference_type operator[](const size_t n) { return _data[n]; } - const_reference_type operator[](const size_t n) const + constexpr const_reference_type operator[](const size_t n) const { return _data[n]; } - void pop_back() + constexpr void pop_back() { _count--; } - void clear() + constexpr void clear() { _count = 0; } - size_t size() const + constexpr size_t size() const { return _count; } - size_t capacity() const + constexpr size_t capacity() const { return _data.size(); } - bool empty() const + constexpr bool empty() const { return _count == 0; } diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index 37d6253b3d..34c726f4c6 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -10,6 +10,7 @@ #pragma once #include "../common.h" +#include "../core/FixedVector.h" #include "../drawing/Drawing.h" #include "../interface/Colour.h" #include "../world/Location.hpp" @@ -137,15 +138,13 @@ struct tunnel_entry struct paint_session { rct_drawpixelinfo DPI; - paint_entry PaintStructs[4000]; + FixedVector PaintStructs; paint_struct* Quadrants[MAX_PAINT_QUADRANTS]; paint_struct PaintHead; uint32_t ViewFlags; uint32_t QuadrantBackIndex; uint32_t QuadrantFrontIndex; const void* CurrentlyDrawnItem; - paint_entry* EndOfPaintStructArray; - paint_entry* NextFreePaintStruct; CoordsXY SpritePosition; paint_struct* LastPS; attached_paint_struct* LastAttachedPS; @@ -172,35 +171,33 @@ struct paint_session constexpr bool NoPaintStructsAvailable() noexcept { - return NextFreePaintStruct >= EndOfPaintStructArray; + return PaintStructs.size() >= PaintStructs.capacity(); } constexpr paint_struct* AllocateNormalPaintEntry() noexcept { - LastPS = &NextFreePaintStruct->basic; - NextFreePaintStruct++; + LastPS = &PaintStructs.emplace_back().basic; return LastPS; } constexpr attached_paint_struct* AllocateAttachedPaintEntry() noexcept { - LastAttachedPS = &NextFreePaintStruct->attached; - NextFreePaintStruct++; + LastAttachedPS = &PaintStructs.emplace_back().attached; return LastAttachedPS; } constexpr paint_string_struct* AllocateStringPaintEntry() noexcept { + auto* string = &PaintStructs.emplace_back().string; if (LastPSString == nullptr) { - PSStringHead = &NextFreePaintStruct->string; + PSStringHead = string; } else { - LastPSString->next = &NextFreePaintStruct->string; + LastPSString->next = string; } - LastPSString = &NextFreePaintStruct->string; - NextFreePaintStruct++; + LastPSString = string; return LastPSString; } }; From 64cbccdda6d58d17abd6d0bb266acb261359a425 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 30 Jan 2021 09:08:57 +0200 Subject: [PATCH 2/2] Re-order members of paint_struct for better code generation --- src/openrct2/paint/Paint.h | 16 ++++++++-------- src/openrct2/paint/Painter.cpp | 16 ++++++---------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index 34c726f4c6..664017af54 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -140,20 +140,23 @@ struct paint_session rct_drawpixelinfo DPI; FixedVector PaintStructs; paint_struct* Quadrants[MAX_PAINT_QUADRANTS]; + paint_struct* LastPS; + paint_string_struct* PSStringHead; + paint_string_struct* LastPSString; + attached_paint_struct* LastAttachedPS; + const TileElement* SurfaceElement; + const void* CurrentlyDrawnItem; + TileElement* PathElementOnSameHeight; + TileElement* TrackElementOnSameHeight; paint_struct PaintHead; uint32_t ViewFlags; uint32_t QuadrantBackIndex; uint32_t QuadrantFrontIndex; - const void* CurrentlyDrawnItem; CoordsXY SpritePosition; - paint_struct* LastPS; - attached_paint_struct* LastAttachedPS; ViewportInteractionItem InteractionType; uint8_t CurrentRotation; support_height SupportSegments[9]; support_height Support; - paint_string_struct* PSStringHead; - paint_string_struct* LastPSString; paint_struct* WoodenSupportsPrependTo; CoordsXY MapPosition; tunnel_entry LeftTunnels[TUNNEL_MAX_COUNT]; @@ -161,9 +164,6 @@ struct paint_session tunnel_entry RightTunnels[TUNNEL_MAX_COUNT]; uint8_t RightTunnelCount; uint8_t VerticalTunnelHeight; - const TileElement* SurfaceElement; - TileElement* PathElementOnSameHeight; - TileElement* TrackElementOnSameHeight; bool DidPassSurface; uint8_t Unk141E9DB; uint16_t WaterHeight; diff --git a/src/openrct2/paint/Painter.cpp b/src/openrct2/paint/Painter.cpp index 2783591fcb..c92fb9a014 100644 --- a/src/openrct2/paint/Painter.cpp +++ b/src/openrct2/paint/Painter.cpp @@ -135,8 +135,7 @@ paint_session* Painter::CreateSession(rct_drawpixelinfo* dpi, uint32_t viewFlags if (_freePaintSessions.empty() == false) { // Re-use. - const size_t idx = _freePaintSessions.size() - 1; - session = _freePaintSessions[idx]; + session = _freePaintSessions.back(); // Shrink by one. _freePaintSessions.pop_back(); @@ -149,17 +148,14 @@ paint_session* Painter::CreateSession(rct_drawpixelinfo* dpi, uint32_t viewFlags } session->DPI = *dpi; - session->EndOfPaintStructArray = &session->PaintStructs[4000 - 1]; - session->NextFreePaintStruct = session->PaintStructs; - session->LastPS = nullptr; - session->LastAttachedPS = nullptr; session->ViewFlags = viewFlags; - for (auto& quadrant : session->Quadrants) - { - quadrant = nullptr; - } session->QuadrantBackIndex = std::numeric_limits::max(); session->QuadrantFrontIndex = 0; + session->PaintStructs.clear(); + + std::fill(std::begin(session->Quadrants), std::end(session->Quadrants), nullptr); + session->LastPS = nullptr; + session->LastAttachedPS = nullptr; session->PSStringHead = nullptr; session->LastPSString = nullptr; session->WoodenSupportsPrependTo = nullptr;