mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-11 01:52:32 +01:00
Fixes #21825 by making 'DrawingLocks' which lock only if multi threaded drawing is enabled. Refactors TTF.cpp to use this. Also cleans up some header files, modernises constants, and removes code to avoid using shared_mutex on MacOS builds. This was originally added because older versions of MacOS didn't support this in the STL.
This commit is contained in:
@@ -21,11 +21,11 @@
|
||||
|
||||
using namespace OpenRCT2::Ui;
|
||||
|
||||
constexpr uint32_t UNUSED_INDEX = 0xFFFFFFFF;
|
||||
constexpr uint32_t kUnusedIndex = 0xFFFFFFFF;
|
||||
|
||||
TextureCache::TextureCache()
|
||||
{
|
||||
std::fill(_indexMap.begin(), _indexMap.end(), UNUSED_INDEX);
|
||||
std::fill(_indexMap.begin(), _indexMap.end(), kUnusedIndex);
|
||||
}
|
||||
|
||||
TextureCache::~TextureCache()
|
||||
@@ -38,13 +38,13 @@ void TextureCache::InvalidateImage(ImageIndex image)
|
||||
unique_lock lock(_mutex);
|
||||
|
||||
uint32_t index = _indexMap[image];
|
||||
if (index == UNUSED_INDEX)
|
||||
if (index == kUnusedIndex)
|
||||
return;
|
||||
|
||||
AtlasTextureInfo& elem = _textureCache.at(index);
|
||||
|
||||
_atlases[elem.index].Free(elem);
|
||||
_indexMap[image] = UNUSED_INDEX;
|
||||
_indexMap[image] = kUnusedIndex;
|
||||
|
||||
if (index == _textureCache.size() - 1)
|
||||
{
|
||||
@@ -76,7 +76,7 @@ BasicTextureInfo TextureCache::GetOrLoadImageTexture(const ImageId imageId)
|
||||
shared_lock lock(_mutex);
|
||||
|
||||
index = _indexMap[imageId.GetIndex()];
|
||||
if (index != UNUSED_INDEX)
|
||||
if (index != kUnusedIndex)
|
||||
{
|
||||
const auto& info = _textureCache[index];
|
||||
return {
|
||||
@@ -144,7 +144,7 @@ BasicTextureInfo TextureCache::GetOrLoadBitmapTexture(ImageIndex image, const vo
|
||||
shared_lock lock(_mutex);
|
||||
|
||||
index = _indexMap[image];
|
||||
if (index != UNUSED_INDEX)
|
||||
if (index != kUnusedIndex)
|
||||
{
|
||||
const auto& info = _textureCache[index];
|
||||
return {
|
||||
@@ -394,7 +394,7 @@ void TextureCache::FreeTextures()
|
||||
// Free array texture
|
||||
glDeleteTextures(1, &_atlasesTexture);
|
||||
_textureCache.clear();
|
||||
std::fill(_indexMap.begin(), _indexMap.end(), UNUSED_INDEX);
|
||||
std::fill(_indexMap.begin(), _indexMap.end(), kUnusedIndex);
|
||||
}
|
||||
|
||||
DrawPixelInfo TextureCache::CreateDPI(int32_t width, int32_t height)
|
||||
|
||||
@@ -10,17 +10,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "GLSLTypes.h"
|
||||
#include "OpenGLAPI.h"
|
||||
|
||||
#include <SDL_pixels.h>
|
||||
#include <array>
|
||||
#include <mutex>
|
||||
#include <openrct2/common.h>
|
||||
#include <openrct2/drawing/Drawing.h>
|
||||
#include <openrct2/drawing/DrawingLock.hpp>
|
||||
#include <openrct2/sprites.h>
|
||||
#ifndef __MACOSX__
|
||||
# include <shared_mutex>
|
||||
#endif
|
||||
#include <shared_mutex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
@@ -209,15 +206,9 @@ namespace OpenRCT2::Ui
|
||||
GLuint _paletteTexture = 0;
|
||||
GLuint _blendPaletteTexture = 0;
|
||||
|
||||
#ifndef __MACOSX__
|
||||
std::shared_mutex _mutex;
|
||||
using shared_lock = std::shared_lock<std::shared_mutex>;
|
||||
using unique_lock = std::unique_lock<std::shared_mutex>;
|
||||
#else
|
||||
std::mutex _mutex;
|
||||
using shared_lock = std::unique_lock<std::mutex>;
|
||||
using unique_lock = std::unique_lock<std::mutex>;
|
||||
#endif
|
||||
using shared_lock = DrawingSharedLock<std::shared_mutex>;
|
||||
using unique_lock = DrawingUniqueLock<std::shared_mutex>;
|
||||
|
||||
public:
|
||||
TextureCache();
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "../drawing/IDrawingEngine.h"
|
||||
#include "../interface/Window.h"
|
||||
#include "../localisation/Currency.h"
|
||||
#include "../localisation/Date.h"
|
||||
#include "../localisation/Language.h"
|
||||
#include "../localisation/Localisation.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../common.h"
|
||||
#include "../core/String.hpp"
|
||||
#include "../drawing/Drawing.h"
|
||||
#include "../localisation/Currency.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
enum class MeasurementFormat : int32_t;
|
||||
@@ -42,7 +42,7 @@ struct GeneralConfiguration
|
||||
bool UncapFPS;
|
||||
bool UseVSync;
|
||||
bool ShowFPS;
|
||||
bool MultiThreading;
|
||||
std::atomic_uint8_t MultiThreading;
|
||||
bool MinimizeFullscreenFocusLoss;
|
||||
bool DisableScreensaver;
|
||||
|
||||
|
||||
52
src/openrct2/drawing/DrawingLock.hpp
Normal file
52
src/openrct2/drawing/DrawingLock.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2024 OpenRCT2 developers
|
||||
*
|
||||
* For a complete list of all authors, please refer to contributors.md
|
||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../config/Config.h"
|
||||
|
||||
template<typename T> class DrawingUniqueLock
|
||||
{
|
||||
T& _mutex;
|
||||
const bool _enabled;
|
||||
|
||||
public:
|
||||
DrawingUniqueLock(T& mutex)
|
||||
: _mutex(mutex)
|
||||
, _enabled(gConfigGeneral.MultiThreading)
|
||||
{
|
||||
if (_enabled)
|
||||
_mutex.lock();
|
||||
}
|
||||
~DrawingUniqueLock()
|
||||
{
|
||||
if (_enabled)
|
||||
_mutex.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> class DrawingSharedLock
|
||||
{
|
||||
T& _mutex;
|
||||
const bool _enabled;
|
||||
|
||||
public:
|
||||
DrawingSharedLock(T& mutex)
|
||||
: _mutex(mutex)
|
||||
, _enabled(gConfigGeneral.MultiThreading)
|
||||
{
|
||||
if (_enabled)
|
||||
_mutex.lock_shared();
|
||||
}
|
||||
~DrawingSharedLock()
|
||||
{
|
||||
if (_enabled)
|
||||
_mutex.unlock_shared();
|
||||
}
|
||||
};
|
||||
@@ -17,17 +17,17 @@
|
||||
# pragma clang diagnostic pop
|
||||
|
||||
# include "../OpenRCT2.h"
|
||||
# include "../config/Config.h"
|
||||
# include "../core/Numerics.hpp"
|
||||
# include "../core/String.hpp"
|
||||
# include "../localisation/LocalisationService.h"
|
||||
# include "../platform/Platform.h"
|
||||
# include "DrawingLock.hpp"
|
||||
# include "TTF.h"
|
||||
|
||||
static bool _ttfInitialised = false;
|
||||
|
||||
# define TTF_SURFACE_CACHE_SIZE 256
|
||||
# define TTF_GETWIDTH_CACHE_SIZE 1024
|
||||
constexpr int32_t kTTFSurfaceCacheSize = 256;
|
||||
constexpr int32_t kTTFGetWidthCacheSize = 1024;
|
||||
|
||||
struct ttf_cache_entry
|
||||
{
|
||||
@@ -45,12 +45,12 @@ struct ttf_getwidth_cache_entry
|
||||
uint32_t lastUseTick;
|
||||
};
|
||||
|
||||
static ttf_cache_entry _ttfSurfaceCache[TTF_SURFACE_CACHE_SIZE] = {};
|
||||
static ttf_cache_entry _ttfSurfaceCache[kTTFSurfaceCacheSize] = {};
|
||||
static int32_t _ttfSurfaceCacheCount = 0;
|
||||
static int32_t _ttfSurfaceCacheHitCount = 0;
|
||||
static int32_t _ttfSurfaceCacheMissCount = 0;
|
||||
|
||||
static ttf_getwidth_cache_entry _ttfGetWidthCache[TTF_GETWIDTH_CACHE_SIZE] = {};
|
||||
static ttf_getwidth_cache_entry _ttfGetWidthCache[kTTFGetWidthCacheSize] = {};
|
||||
static int32_t _ttfGetWidthCacheCount = 0;
|
||||
static int32_t _ttfGetWidthCacheHitCount = 0;
|
||||
static int32_t _ttfGetWidthCacheMissCount = 0;
|
||||
@@ -66,26 +66,6 @@ static bool TTFGetSize(TTF_Font* font, std::string_view text, int32_t* outWidth,
|
||||
static void TTFToggleHinting(bool);
|
||||
static TTFSurface* TTFRender(TTF_Font* font, std::string_view text);
|
||||
|
||||
template<typename T> class FontLockHelper
|
||||
{
|
||||
T& _mutex;
|
||||
const bool _enabled;
|
||||
|
||||
public:
|
||||
FontLockHelper(T& mutex)
|
||||
: _mutex(mutex)
|
||||
, _enabled(gConfigGeneral.MultiThreading)
|
||||
{
|
||||
if (_enabled)
|
||||
_mutex.lock();
|
||||
}
|
||||
~FontLockHelper()
|
||||
{
|
||||
if (_enabled)
|
||||
_mutex.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
static void TTFToggleHinting(bool)
|
||||
{
|
||||
if (!LocalisationService_UseTrueTypeFont())
|
||||
@@ -108,7 +88,7 @@ static void TTFToggleHinting(bool)
|
||||
|
||||
bool TTFInitialise()
|
||||
{
|
||||
FontLockHelper<std::mutex> lock(_mutex);
|
||||
DrawingUniqueLock<std::mutex> lock(_mutex);
|
||||
|
||||
if (_ttfInitialised)
|
||||
return true;
|
||||
@@ -147,7 +127,7 @@ bool TTFInitialise()
|
||||
|
||||
void TTFDispose()
|
||||
{
|
||||
FontLockHelper<std::mutex> lock(_mutex);
|
||||
DrawingUniqueLock<std::mutex> lock(_mutex);
|
||||
|
||||
if (!_ttfInitialised)
|
||||
return;
|
||||
@@ -203,7 +183,7 @@ static void TTFSurfaceCacheDispose(ttf_cache_entry* entry)
|
||||
|
||||
static void TTFSurfaceCacheDisposeAll()
|
||||
{
|
||||
for (int32_t i = 0; i < TTF_SURFACE_CACHE_SIZE; i++)
|
||||
for (int32_t i = 0; i < kTTFSurfaceCacheSize; i++)
|
||||
{
|
||||
TTFSurfaceCacheDispose(&_ttfSurfaceCache[i]);
|
||||
_ttfSurfaceCacheCount--;
|
||||
@@ -212,7 +192,7 @@ static void TTFSurfaceCacheDisposeAll()
|
||||
|
||||
void TTFToggleHinting()
|
||||
{
|
||||
FontLockHelper<std::mutex> lock(_mutex);
|
||||
DrawingUniqueLock<std::mutex> lock(_mutex);
|
||||
TTFToggleHinting(true);
|
||||
}
|
||||
|
||||
@@ -221,11 +201,11 @@ TTFSurface* TTFSurfaceCacheGetOrAdd(TTF_Font* font, std::string_view text)
|
||||
ttf_cache_entry* entry;
|
||||
|
||||
uint32_t hash = TTFSurfaceCacheHash(font, text);
|
||||
int32_t index = hash % TTF_SURFACE_CACHE_SIZE;
|
||||
int32_t index = hash % kTTFSurfaceCacheSize;
|
||||
|
||||
FontLockHelper<std::mutex> lock(_mutex);
|
||||
DrawingUniqueLock<std::mutex> lock(_mutex);
|
||||
|
||||
for (int32_t i = 0; i < TTF_SURFACE_CACHE_SIZE; i++)
|
||||
for (int32_t i = 0; i < kTTFSurfaceCacheSize; i++)
|
||||
{
|
||||
entry = &_ttfSurfaceCache[index];
|
||||
|
||||
@@ -246,7 +226,7 @@ TTFSurface* TTFSurfaceCacheGetOrAdd(TTF_Font* font, std::string_view text)
|
||||
}
|
||||
|
||||
// Check if next entry is a hit
|
||||
if (++index >= TTF_SURFACE_CACHE_SIZE)
|
||||
if (++index >= kTTFSurfaceCacheSize)
|
||||
index = 0;
|
||||
}
|
||||
|
||||
@@ -283,7 +263,7 @@ static void TTFGetWidthCacheDispose(ttf_getwidth_cache_entry* entry)
|
||||
|
||||
static void TTFGetWidthCacheDisposeAll()
|
||||
{
|
||||
for (int32_t i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++)
|
||||
for (int32_t i = 0; i < kTTFGetWidthCacheSize; i++)
|
||||
{
|
||||
TTFGetWidthCacheDispose(&_ttfGetWidthCache[i]);
|
||||
_ttfGetWidthCacheCount--;
|
||||
@@ -295,11 +275,11 @@ uint32_t TTFGetWidthCacheGetOrAdd(TTF_Font* font, std::string_view text)
|
||||
ttf_getwidth_cache_entry* entry;
|
||||
|
||||
uint32_t hash = TTFSurfaceCacheHash(font, text);
|
||||
int32_t index = hash % TTF_GETWIDTH_CACHE_SIZE;
|
||||
int32_t index = hash % kTTFGetWidthCacheSize;
|
||||
|
||||
FontLockHelper<std::mutex> lock(_mutex);
|
||||
DrawingUniqueLock<std::mutex> lock(_mutex);
|
||||
|
||||
for (int32_t i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++)
|
||||
for (int32_t i = 0; i < kTTFGetWidthCacheSize; i++)
|
||||
{
|
||||
entry = &_ttfGetWidthCache[index];
|
||||
|
||||
@@ -320,7 +300,7 @@ uint32_t TTFGetWidthCacheGetOrAdd(TTF_Font* font, std::string_view text)
|
||||
}
|
||||
|
||||
// Check if next entry is a hit
|
||||
if (++index >= TTF_GETWIDTH_CACHE_SIZE)
|
||||
if (++index >= kTTFGetWidthCacheSize)
|
||||
index = 0;
|
||||
}
|
||||
|
||||
@@ -343,7 +323,7 @@ uint32_t TTFGetWidthCacheGetOrAdd(TTF_Font* font, std::string_view text)
|
||||
|
||||
TTFFontDescriptor* TTFGetFontFromSpriteBase(FontStyle fontStyle)
|
||||
{
|
||||
FontLockHelper<std::mutex> lock(_mutex);
|
||||
DrawingUniqueLock<std::mutex> lock(_mutex);
|
||||
return &gCurrentTTFFontSet->size[EnumValue(fontStyle)];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user