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.
// 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);
@ -867,6 +868,7 @@ static void record_session(const paint_session* session, std::vector<paint_sessi
quad = reinterpret_cast<paint_struct*>(
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)

View File

@ -139,9 +139,6 @@ static paint_struct* CreateNormalPaintStruct(
paint_session* session, const uint32_t image_id, const CoordsXYZ& offset, const CoordsXYZ& boundBoxSize,
const CoordsXYZ& boundBoxOffset)
{
if (session->NoPaintStructsAvailable())
return nullptr;
auto* const g1 = gfx_get_g1_element(image_id & 0x7FFFF);
if (g1 == nullptr)
{
@ -162,7 +159,12 @@ static paint_struct* CreateNormalPaintStruct(
const auto rotBoundBoxOffset = CoordsXYZ{ boundBoxOffset.Rotate(swappedRotation), boundBoxOffset.z };
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->x = imagePos.x;
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)
{
if (session->NoPaintStructsAvailable())
{
return false;
}
attached_paint_struct* previousAttachedPS = session->LastAttachedPS;
auto* previousAttachedPS = session->LastAttachedPS;
if (previousAttachedPS == nullptr)
{
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->x = x;
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)
{
if (session->NoPaintStructsAvailable())
{
return false;
}
paint_struct* masterPs = session->LastPS;
auto* masterPs = session->LastPS;
if (masterPs == nullptr)
{
return false;
}
attached_paint_struct* ps = session->AllocateAttachedPaintEntry();
auto* ps = session->AllocateAttachedPaintEntry();
if (ps == nullptr)
{
return false;
}
ps->image_id = image_id;
ps->x = x;
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,
uint32_t rotation)
{
if (session->NoPaintStructsAvailable())
auto* ps = session->AllocateStringPaintEntry();
if (ps == nullptr)
{
return;
}
@ -930,7 +933,6 @@ void PaintFloatingMoneyEffect(
};
const auto coord = translate_3d_to_2d_with_z(rotation, position);
paint_string_struct* ps = session->AllocateStringPaintEntry();
ps->string_id = string_id;
ps->next = nullptr;
ps->args[0] = amount;

View File

@ -15,6 +15,9 @@
#include "../interface/Colour.h"
#include "../world/Location.hpp"
#include <mutex>
#include <thread>
struct TileElement;
enum class ViewportInteractionItem : uint8_t;
@ -135,10 +138,33 @@ struct tunnel_entry
#define MAX_PAINT_QUADRANTS 512
#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
{
rct_drawpixelinfo DPI;
FixedVector<paint_entry, 4000> PaintStructs;
// FixedVector<paint_entry, 4000> PaintStructs;
PaintStructPool* SharedPaintStructPool;
paint_struct* Quadrants[MAX_PAINT_QUADRANTS];
paint_struct* LastPS;
paint_string_struct* PSStringHead;
@ -169,36 +195,46 @@ struct paint_session
uint16_t WaterHeight;
uint32_t TrackColours[4];
constexpr bool NoPaintStructsAvailable() noexcept
paint_struct* AllocateNormalPaintEntry() noexcept
{
return PaintStructs.size() >= PaintStructs.capacity();
}
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)
auto* entry = SharedPaintStructPool->Allocate();
if (entry != 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 LastPSString;
return nullptr;
}
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)
{
_paintStructPool.Clear();
auto dpi = de.GetDrawingPixelInfo();
if (gIntroState != IntroState::None)
{
@ -151,7 +153,7 @@ paint_session* Painter::CreateSession(rct_drawpixelinfo* dpi, uint32_t viewFlags
session->ViewFlags = viewFlags;
session->QuadrantBackIndex = std::numeric_limits<uint32_t>::max();
session->QuadrantFrontIndex = 0;
session->PaintStructs.clear();
session->SharedPaintStructPool = &_paintStructPool;
std::fill(std::begin(session->Quadrants), std::end(session->Quadrants), nullptr);
session->LastPS = nullptr;

View File

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