From 65ef018e4ebfcd8ce65401bd97332faf28808940 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 19 Feb 2019 16:26:11 +0100 Subject: [PATCH] Move paint_session_alloc and paint_session_free into Painter. --- .../drawing/engines/opengl/TextureCache.cpp | 10 ++-- .../drawing/engines/opengl/TextureCache.h | 12 ++++- src/openrct2/Context.cpp | 6 +-- src/openrct2/paint/Paint.cpp | 43 +++-------------- src/openrct2/paint/Painter.cpp | 47 +++++++++++++++++++ src/openrct2/paint/Painter.h | 8 +++- 6 files changed, 78 insertions(+), 48 deletions(-) diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 117b188b0b..8272b1a4ba 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -30,7 +30,7 @@ TextureCache::~TextureCache() void TextureCache::InvalidateImage(uint32_t image) { - std::unique_lock lock(_mutex); + std::unique_lock lock(_mutex); uint32_t index = _indexMap[image]; if (index == UNUSED_INDEX) @@ -69,7 +69,7 @@ BasicTextureInfo TextureCache::GetOrLoadImageTexture(uint32_t image) // Try to read cached texture first. { - std::shared_lock lock(_mutex); + shared_lock lock(_mutex); index = _indexMap[image]; if (index != UNUSED_INDEX) @@ -83,7 +83,7 @@ BasicTextureInfo TextureCache::GetOrLoadImageTexture(uint32_t image) } // Load new texture. - std::unique_lock lock(_mutex); + std::unique_lock lock(_mutex); index = (uint32_t)_textureCache.size(); @@ -102,7 +102,7 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32_t image, uint8_t* pa // Try to read cached texture first. { - std::shared_lock lock(_mutex); + shared_lock lock(_mutex); std::copy_n(palette, sizeof(glyphId.Palette), (uint8_t*)&glyphId.Palette); @@ -118,7 +118,7 @@ BasicTextureInfo TextureCache::GetOrLoadGlyphTexture(uint32_t image, uint8_t* pa } // Load new texture. - std::unique_lock lock(_mutex); + std::unique_lock lock(_mutex); auto cacheInfo = LoadGlyphTexture(image, palette); auto it = _glyphTextureMap.insert(std::make_pair(glyphId, cacheInfo)); diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h index bd3f8c6b42..c9cebd2e73 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.h +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.h @@ -15,8 +15,11 @@ #include #include #include +#include #include -#include +#ifndef __MACOSX__ +# include +#endif #include #include @@ -199,7 +202,14 @@ private: std::array _indexMap; GLuint _paletteTexture = 0; + +#ifndef __MACOSX__ std::shared_mutex _mutex; + typedef std::shared_lock shared_lock; +#else + std::mutex _mutex; + typedef std::unique_lock shared_lock; +#endif public: TextureCache(); diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index a8770c749f..7a39417afc 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -133,6 +133,7 @@ namespace OpenRCT2 , _audioContext(audioContext) , _uiContext(uiContext) , _localisationService(std::make_unique(env)) + , _painter(std::make_unique(uiContext)) { // Can't have more than one context currently. Guard::Assert(Instance == nullptr); @@ -415,6 +416,7 @@ namespace OpenRCT2 lightfx_init(); #endif } + gScenarioTicks = 0; util_srand((uint32_t)time(nullptr)); input_reset_place_obj_modifier(); @@ -430,7 +432,6 @@ namespace OpenRCT2 void InitialiseDrawingEngine() final override { assert(_drawingEngine == nullptr); - assert(_painter == nullptr); _drawingEngineType = gConfigGeneral.drawing_engine; @@ -457,7 +458,6 @@ namespace OpenRCT2 } else { - _painter = std::make_unique(_uiContext); try { drawingEngine->Initialise(); @@ -466,7 +466,6 @@ namespace OpenRCT2 } catch (const std::exception& ex) { - _painter = nullptr; if (_drawingEngineType == DRAWING_ENGINE_SOFTWARE) { _drawingEngineType = DRAWING_ENGINE_NONE; @@ -491,7 +490,6 @@ namespace OpenRCT2 void DisposeDrawingEngine() final override { _drawingEngine = nullptr; - _painter = nullptr; } bool LoadParkFromFile(const std::string& path, bool loadTitleScreenOnFail) final override diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index 853c5090d4..477e7a3aa0 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -9,11 +9,13 @@ #include "Paint.h" +#include "../Context.h" #include "../config/Config.h" #include "../drawing/Drawing.h" #include "../interface/Viewport.h" #include "../localisation/Localisation.h" #include "../localisation/LocalisationService.h" +#include "../paint/Painter.h" #include "sprite/Paint.Sprite.h" #include "tile_element/Paint.TileElement.h" @@ -21,6 +23,8 @@ #include #include +using namespace OpenRCT2; + // Globals for paint clipping uint8_t gClipHeight = 128; // Default to middle value LocationXY8 gClipSelectionA = { 0, 0 }; @@ -48,34 +52,12 @@ bool gShowDirtyVisuals; bool gPaintBoundingBoxes; bool gPaintBlockedTiles; -static void paint_session_init(paint_session* session, rct_drawpixelinfo* dpi, uint32_t viewFlags); static void paint_attached_ps(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t viewFlags); static void paint_ps_image_with_bounding_boxes( rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t imageId, int16_t x, int16_t y); static void paint_ps_image(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t imageId, int16_t x, int16_t y); static uint32_t paint_ps_colourify_image(uint32_t imageId, uint8_t spriteType, uint32_t viewFlags); -static void paint_session_init(paint_session* session, rct_drawpixelinfo* dpi, uint32_t viewFlags) -{ - session->DPI = *dpi; - session->EndOfPaintStructArray = &session->PaintStructs[4000 - 1]; - session->NextFreePaintStruct = session->PaintStructs; - session->LastRootPS = nullptr; - session->UnkF1AD2C = nullptr; - session->ViewFlags = viewFlags; - for (auto& quadrant : session->Quadrants) - { - quadrant = nullptr; - } - session->QuadrantBackIndex = std::numeric_limits::max(); - session->QuadrantFrontIndex = 0; - session->PSStringHead = nullptr; - session->LastPSString = nullptr; - session->WoodenSupportsPrependTo = nullptr; - session->CurrentlyDrawnItem = nullptr; - session->SurfaceElement = nullptr; -} - static void paint_session_add_ps_to_quadrant(paint_session* session, paint_struct* ps, int32_t positionHash) { uint32_t paintQuadrantIndex = std::clamp(positionHash / 32, 0, MAX_PAINT_QUADRANTS - 1); @@ -732,25 +714,12 @@ static void draw_pixel_info_crop_by_zoom(rct_drawpixelinfo* dpi) paint_session* paint_session_alloc(rct_drawpixelinfo* dpi, uint32_t viewFlags) { - paint_session* session = nullptr; - - if (_freePaintSessions.empty()) - { - session = new paint_session(); - } - else - { - session = _freePaintSessions[_freePaintSessions.size() - 1]; - _freePaintSessions.resize(_freePaintSessions.size() - 1); - } - - paint_session_init(session, dpi, viewFlags); - return session; + return GetContext()->GetPainter()->CreateSession(dpi, viewFlags); } void paint_session_free([[maybe_unused]] paint_session* session) { - _freePaintSessions.push_back(session); + GetContext()->GetPainter()->ReleaseSession(session); } /** diff --git a/src/openrct2/paint/Painter.cpp b/src/openrct2/paint/Painter.cpp index 888a84190f..e9498eff9e 100644 --- a/src/openrct2/paint/Painter.cpp +++ b/src/openrct2/paint/Painter.cpp @@ -20,6 +20,7 @@ #include "../interface/InteractiveConsole.h" #include "../localisation/FormatCodes.h" #include "../localisation/Language.h" +#include "../paint/Paint.h" #include "../title/TitleScreen.h" #include "../ui/UiContext.h" @@ -140,3 +141,49 @@ void Painter::MeasureFPS() } _lastSecond = currentTime; } + +paint_session* Painter::CreateSession(rct_drawpixelinfo* dpi, uint32_t viewFlags) +{ + paint_session* session = nullptr; + + if (_freePaintSessions.empty() == false) + { + // Re-use. + const size_t idx = _freePaintSessions.size() - 1; + session = _freePaintSessions[idx]; + + // Shrink by one. + _freePaintSessions.pop_back(); + } + else + { + // Create new one in pool. + _paintSessionPool.emplace_back(std::make_unique()); + session = _paintSessionPool.back().get(); + } + + session->DPI = *dpi; + session->EndOfPaintStructArray = &session->PaintStructs[4000 - 1]; + session->NextFreePaintStruct = session->PaintStructs; + session->LastRootPS = nullptr; + session->UnkF1AD2C = nullptr; + session->ViewFlags = viewFlags; + for (auto& quadrant : session->Quadrants) + { + quadrant = nullptr; + } + session->QuadrantBackIndex = std::numeric_limits::max(); + session->QuadrantFrontIndex = 0; + session->PSStringHead = nullptr; + session->LastPSString = nullptr; + session->WoodenSupportsPrependTo = nullptr; + session->CurrentlyDrawnItem = nullptr; + session->SurfaceElement = nullptr; + + return session; +} + +void Painter::ReleaseSession(paint_session* session) +{ + _freePaintSessions.push_back(session); +} diff --git a/src/openrct2/paint/Painter.h b/src/openrct2/paint/Painter.h index cb338a0cfd..c2b81e6b4b 100644 --- a/src/openrct2/paint/Painter.h +++ b/src/openrct2/paint/Painter.h @@ -10,9 +10,11 @@ #pragma once #include "../common.h" +#include "Paint.h" #include #include +#include struct rct_drawpixelinfo; @@ -34,7 +36,8 @@ namespace OpenRCT2 { private: std::shared_ptr const _uiContext; - + std::vector> _paintSessionPool; + std::vector _freePaintSessions; time_t _lastSecond = 0; int32_t _currentFPS = 0; int32_t _frames = 0; @@ -43,6 +46,9 @@ namespace OpenRCT2 explicit Painter(const std::shared_ptr& uiContext); void Paint(Drawing::IDrawingEngine & de); + paint_session* CreateSession(rct_drawpixelinfo * dpi, uint32_t viewFlags); + void ReleaseSession(paint_session * session); + private: void PaintReplayNotice(rct_drawpixelinfo * dpi, const char* text); void PaintFPS(rct_drawpixelinfo * dpi);