Increase paint struct limit by using shared pool

This commit is contained in:
Ted John 2021-04-27 01:27:49 +01:00
parent 1aec32056d
commit cb6d471560
5 changed files with 90 additions and 47 deletions

View File

@ -852,6 +852,7 @@ static void record_session(const paint_session* session, std::vector<paint_sessi
// This is done to extract the session for benchmark. // 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; // 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. // there is no column information embedded in the session itself.
/*
(*recorded_sessions)[record_index] = (*session); (*recorded_sessions)[record_index] = (*session);
paint_session* session_copy = &recorded_sessions->at(record_index); paint_session* session_copy = &recorded_sessions->at(record_index);
@ -867,6 +868,7 @@ static void record_session(const paint_session* session, std::vector<paint_sessi
quad = reinterpret_cast<paint_struct*>( quad = reinterpret_cast<paint_struct*>(
quad ? int(quad - &session->PaintStructs[0].basic) : std::size(session->Quadrants)); quad ? int(quad - &session->PaintStructs[0].basic) : std::size(session->Quadrants));
} }
*/
} }
static void viewport_fill_column(paint_session* session, std::vector<paint_session>* recorded_sessions, size_t record_index) static void viewport_fill_column(paint_session* session, std::vector<paint_session>* recorded_sessions, size_t record_index)

View File

@ -139,9 +139,6 @@ static paint_struct* CreateNormalPaintStruct(
paint_session* session, const uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize, paint_session* session, const uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
const CoordsXYZ& boundBoxOffset) const CoordsXYZ& boundBoxOffset)
{ {
if (session->NoPaintStructsAvailable())
return nullptr;
auto* const g1 = gfx_get_g1_element(image_id & 0x7FFFF); auto* const g1 = gfx_get_g1_element(image_id & 0x7FFFF);
if (g1 == nullptr) if (g1 == nullptr)
{ {
@ -162,7 +159,12 @@ static paint_struct* CreateNormalPaintStruct(
const auto rotBoundBoxOffset = CoordsXYZ{ boundBoxOffset.Rotate(swappedRotation), boundBoxOffset.z }; const auto rotBoundBoxOffset = CoordsXYZ{ boundBoxOffset.Rotate(swappedRotation), boundBoxOffset.z };
const auto rotBoundBoxSize = RotateBoundBoxSize(boundBoxSize, session->CurrentRotation); const auto rotBoundBoxSize = RotateBoundBoxSize(boundBoxSize, session->CurrentRotation);
paint_struct* ps = session->AllocateNormalPaintEntry(); auto* ps = session->AllocateNormalPaintEntry();
if (ps == nullptr)
{
return nullptr;
}
ps->image_id = image_id; ps->image_id = image_id;
ps->x = imagePos.x; ps->x = imagePos.x;
ps->y = imagePos.y; ps->y = imagePos.y;
@ -847,18 +849,18 @@ paint_struct* PaintAddImageAsChild(
*/ */
bool PaintAttachToPreviousAttach(paint_session* session, uint32_t image_id, int16_t x, int16_t y) bool PaintAttachToPreviousAttach(paint_session* session, uint32_t image_id, int16_t x, int16_t y)
{ {
if (session->NoPaintStructsAvailable()) auto* previousAttachedPS = session->LastAttachedPS;
{
return false;
}
attached_paint_struct* previousAttachedPS = session->LastAttachedPS;
if (previousAttachedPS == nullptr) if (previousAttachedPS == nullptr)
{ {
return PaintAttachToPreviousPS(session, image_id, x, y); return PaintAttachToPreviousPS(session, image_id, x, y);
} }
attached_paint_struct* ps = session->AllocateAttachedPaintEntry(); auto* ps = session->AllocateAttachedPaintEntry();
if (ps == nullptr)
{
return false;
}
ps->image_id = image_id; ps->image_id = image_id;
ps->x = x; ps->x = x;
ps->y = y; ps->y = y;
@ -880,18 +882,18 @@ bool PaintAttachToPreviousAttach(paint_session* session, uint32_t image_id, int1
*/ */
bool PaintAttachToPreviousPS(paint_session* session, uint32_t image_id, int16_t x, int16_t y) bool PaintAttachToPreviousPS(paint_session* session, uint32_t image_id, int16_t x, int16_t y)
{ {
if (session->NoPaintStructsAvailable()) auto* masterPs = session->LastPS;
{
return false;
}
paint_struct* masterPs = session->LastPS;
if (masterPs == nullptr) if (masterPs == nullptr)
{ {
return false; return false;
} }
attached_paint_struct* ps = session->AllocateAttachedPaintEntry(); auto* ps = session->AllocateAttachedPaintEntry();
if (ps == nullptr)
{
return false;
}
ps->image_id = image_id; ps->image_id = image_id;
ps->x = x; ps->x = x;
ps->y = y; ps->y = y;
@ -918,7 +920,8 @@ void PaintFloatingMoneyEffect(
paint_session* session, money32 amount, rct_string_id string_id, int16_t y, int16_t z, int8_t y_offsets[], int16_t offset_x, paint_session* session, money32 amount, rct_string_id string_id, int16_t y, int16_t z, int8_t y_offsets[], int16_t offset_x,
uint32_t rotation) uint32_t rotation)
{ {
if (session->NoPaintStructsAvailable()) auto* ps = session->AllocateStringPaintEntry();
if (ps == nullptr)
{ {
return; return;
} }
@ -930,7 +933,6 @@ void PaintFloatingMoneyEffect(
}; };
const auto coord = translate_3d_to_2d_with_z(rotation, position); const auto coord = translate_3d_to_2d_with_z(rotation, position);
paint_string_struct* ps = session->AllocateStringPaintEntry();
ps->string_id = string_id; ps->string_id = string_id;
ps->next = nullptr; ps->next = nullptr;
ps->args[0] = amount; ps->args[0] = amount;

View File

@ -15,6 +15,9 @@
#include "../interface/Colour.h" #include "../interface/Colour.h"
#include "../world/Location.hpp" #include "../world/Location.hpp"
#include <mutex>
#include <thread>
struct TileElement; struct TileElement;
enum class ViewportInteractionItem : uint8_t; enum class ViewportInteractionItem : uint8_t;
@ -135,10 +138,33 @@ struct tunnel_entry
#define MAX_PAINT_QUADRANTS 512 #define MAX_PAINT_QUADRANTS 512
#define TUNNEL_MAX_COUNT 65 #define TUNNEL_MAX_COUNT 65
struct PaintStructPool
{
FixedVector<paint_entry, 0x80000> PaintStructs;
std::mutex _mutex;
paint_entry* Allocate()
{
std::lock_guard<std::mutex> guard(_mutex);
if (PaintStructs.size() < PaintStructs.capacity())
{
return &PaintStructs.emplace_back();
}
return nullptr;
}
void Clear()
{
PaintStructs.clear();
}
};
struct paint_session struct paint_session
{ {
rct_drawpixelinfo DPI; rct_drawpixelinfo DPI;
FixedVector<paint_entry, 4000> PaintStructs; // FixedVector<paint_entry, 4000> PaintStructs;
PaintStructPool* SharedPaintStructPool;
paint_struct* Quadrants[MAX_PAINT_QUADRANTS]; paint_struct* Quadrants[MAX_PAINT_QUADRANTS];
paint_struct* LastPS; paint_struct* LastPS;
paint_string_struct* PSStringHead; paint_string_struct* PSStringHead;
@ -169,36 +195,46 @@ struct paint_session
uint16_t WaterHeight; uint16_t WaterHeight;
uint32_t TrackColours[4]; uint32_t TrackColours[4];
constexpr bool NoPaintStructsAvailable() noexcept paint_struct* AllocateNormalPaintEntry() noexcept
{ {
return PaintStructs.size() >= PaintStructs.capacity(); auto* entry = SharedPaintStructPool->Allocate();
} if (entry != nullptr)
constexpr paint_struct* AllocateNormalPaintEntry() noexcept
{
LastPS = &PaintStructs.emplace_back().basic;
return LastPS;
}
constexpr attached_paint_struct* AllocateAttachedPaintEntry() noexcept
{
LastAttachedPS = &PaintStructs.emplace_back().attached;
return LastAttachedPS;
}
constexpr paint_string_struct* AllocateStringPaintEntry() noexcept
{
auto* string = &PaintStructs.emplace_back().string;
if (LastPSString == nullptr)
{ {
PSStringHead = string; LastPS = &entry->basic;
return LastPS;
} }
else return nullptr;
}
attached_paint_struct* AllocateAttachedPaintEntry() noexcept
{
auto* entry = SharedPaintStructPool->Allocate();
if (entry != nullptr)
{ {
LastPSString->next = string; LastAttachedPS = &entry->attached;
return LastAttachedPS;
} }
LastPSString = string; return nullptr;
return LastPSString; }
paint_string_struct* AllocateStringPaintEntry() noexcept
{
auto* entry = SharedPaintStructPool->Allocate();
if (entry != nullptr)
{
auto* string = &entry->string;
if (LastPSString == nullptr)
{
PSStringHead = string;
}
else
{
LastPSString->next = string;
}
LastPSString = string;
return LastPSString;
}
return nullptr;
} }
}; };

View File

@ -37,6 +37,8 @@ Painter::Painter(const std::shared_ptr<IUiContext>& uiContext)
void Painter::Paint(IDrawingEngine& de) void Painter::Paint(IDrawingEngine& de)
{ {
_paintStructPool.Clear();
auto dpi = de.GetDrawingPixelInfo(); auto dpi = de.GetDrawingPixelInfo();
if (gIntroState != IntroState::None) if (gIntroState != IntroState::None)
{ {
@ -151,7 +153,7 @@ paint_session* Painter::CreateSession(rct_drawpixelinfo* dpi, uint32_t viewFlags
session->ViewFlags = viewFlags; session->ViewFlags = viewFlags;
session->QuadrantBackIndex = std::numeric_limits<uint32_t>::max(); session->QuadrantBackIndex = std::numeric_limits<uint32_t>::max();
session->QuadrantFrontIndex = 0; session->QuadrantFrontIndex = 0;
session->PaintStructs.clear(); session->SharedPaintStructPool = &_paintStructPool;
std::fill(std::begin(session->Quadrants), std::end(session->Quadrants), nullptr); std::fill(std::begin(session->Quadrants), std::end(session->Quadrants), nullptr);
session->LastPS = nullptr; session->LastPS = nullptr;

View File

@ -38,6 +38,7 @@ namespace OpenRCT2
std::shared_ptr<Ui::IUiContext> const _uiContext; std::shared_ptr<Ui::IUiContext> const _uiContext;
std::vector<std::unique_ptr<paint_session>> _paintSessionPool; std::vector<std::unique_ptr<paint_session>> _paintSessionPool;
std::vector<paint_session*> _freePaintSessions; std::vector<paint_session*> _freePaintSessions;
PaintStructPool _paintStructPool;
time_t _lastSecond = 0; time_t _lastSecond = 0;
int32_t _currentFPS = 0; int32_t _currentFPS = 0;
int32_t _frames = 0; int32_t _frames = 0;