Remove duplicate code from the text rendering backends

This commit is contained in:
Henrik Rydgård 2024-06-01 09:58:58 +02:00
parent d6b6d087c0
commit 28cf69f67e
14 changed files with 45 additions and 273 deletions

View File

@ -164,6 +164,49 @@ bool TextDrawer::DrawStringBitmapRect(std::vector<uint8_t> &bitmapData, TextStri
return DrawStringBitmap(bitmapData, entry, texFormat, toDraw.c_str(), align, fullColor);
}
void TextDrawer::ClearCache() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
fontHash_ = 0;
}
void TextDrawer::OncePerFrame() {
frameCount_++;
// If DPI changed (small-mode, future proper monitor DPI support), drop everything.
float newDpiScale = CalculateDPIScale();
if (newDpiScale != dpiScale_) {
INFO_LOG(G3D, "DPI Scale changed (%f to %f) - wiping font cache (%d items)", dpiScale_, newDpiScale, (int)cache_.size());
dpiScale_ = newDpiScale;
ClearCache();
ClearFonts();
}
// Drop old strings. Use a prime number to reduce clashing with other rhythms
if (frameCount_ % 23 == 0) {
for (auto iter = cache_.begin(); iter != cache_.end();) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
if (iter->second->texture)
iter->second->texture->Release();
cache_.erase(iter++);
} else {
iter++;
}
}
for (auto iter = sizeCache_.begin(); iter != sizeCache_.end(); ) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
sizeCache_.erase(iter++);
} else {
iter++;
}
}
}
}
TextDrawer *TextDrawer::Create(Draw::DrawContext *draw) {
TextDrawer *drawer = nullptr;
#if defined(__LIBRETRO__)

View File

@ -56,7 +56,7 @@ public:
virtual bool DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) = 0;
bool DrawStringBitmapRect(std::vector<uint8_t> &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, const Bounds &bounds, int align, bool fullColor);
// Use for housekeeping like throwing out old strings.
virtual void OncePerFrame() = 0;
void OncePerFrame();
float CalculateDPIScale();
void SetForcedDPIScale(float dpi) {
@ -69,9 +69,9 @@ public:
protected:
TextDrawer(Draw::DrawContext *draw);
void ClearCache();
virtual bool SupportsColorEmoji() const = 0;
virtual void ClearCache() = 0;
virtual void ClearFonts() = 0;
void WrapString(std::string &out, std::string_view str, float maxWidth, int flags);

View File

@ -189,47 +189,4 @@ void TextDrawerAndroid::ClearFonts() {
fontMap_.clear(); // size is precomputed using dpiScale_.
}
void TextDrawerAndroid::ClearCache() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
}
void TextDrawerAndroid::OncePerFrame() {
frameCount_++;
// If DPI changed (small-mode, future proper monitor DPI support), drop everything.
float newDpiScale = CalculateDPIScale();
if (newDpiScale != dpiScale_) {
// TODO: Don't bother if it's a no-op (cache already empty)
INFO_LOG(G3D, "DPI Scale changed (%f to %f) - wiping font cache (%d items, %d fonts)", dpiScale_, newDpiScale, (int)cache_.size(), (int)fontMap_.size());
dpiScale_ = newDpiScale;
ClearCache();
ClearFonts();
}
// Drop old strings. Use a prime number to reduce clashing with other rhythms
if (frameCount_ % 23 == 0) {
for (auto iter = cache_.begin(); iter != cache_.end();) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
if (iter->second->texture)
iter->second->texture->Release();
cache_.erase(iter++);
} else {
iter++;
}
}
for (auto iter = sizeCache_.begin(); iter != sizeCache_.end(); ) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
sizeCache_.erase(iter++);
} else {
iter++;
}
}
}
}
#endif

View File

@ -23,13 +23,10 @@ public:
void SetFont(uint32_t fontHandle) override; // Shortcut once you've set the font once.
void MeasureString(std::string_view str, float *w, float *h) override;
bool DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) override;
// Use for housekeeping like throwing out old strings.
void OncePerFrame() override;
protected:
bool SupportsColorEmoji() const override { return true; }
void ClearCache() override;
void ClearFonts() override;
private:

View File

@ -20,13 +20,10 @@ public:
void SetFont(uint32_t fontHandle) override; // Shortcut once you've set the font once.
void MeasureString(std::string_view str, float *w, float *h) override;
bool DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) override;
// Use for housekeeping like throwing out old strings.
void OncePerFrame() override;
protected:
bool SupportsColorEmoji() const override { return true; }
void ClearCache() override;
void ClearFonts() override;
TextDrawerContext *ctx_;

View File

@ -290,46 +290,4 @@ bool TextDrawerCocoa::DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStr
return true;
}
void TextDrawerCocoa::ClearCache() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
}
void TextDrawerCocoa::OncePerFrame() {
frameCount_++;
// If DPI changed (small-mode, future proper monitor DPI support), drop everything.
float newDpiScale = CalculateDPIScale();
if (newDpiScale != dpiScale_) {
INFO_LOG(G3D, "TextDrawerCocoa: DPI scale: %0.1f", newDpiScale);
dpiScale_ = newDpiScale;
ClearCache();
ClearFonts();
}
// Drop old strings. Use a prime number to reduce clashing with other rhythms
if (frameCount_ % 23 == 0) {
for (auto iter = cache_.begin(); iter != cache_.end();) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
if (iter->second->texture)
iter->second->texture->Release();
cache_.erase(iter++);
} else {
iter++;
}
}
for (auto iter = sizeCache_.begin(); iter != sizeCache_.end(); ) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
sizeCache_.erase(iter++);
} else {
iter++;
}
}
}
}
#endif

View File

@ -135,45 +135,4 @@ void TextDrawerQt::ClearFonts() {
fontHash_ = 0;
}
void TextDrawerQt::ClearCache() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
}
void TextDrawerQt::OncePerFrame() {
frameCount_++;
// If DPI changed (small-mode, future proper monitor DPI support), drop everything.
float newDpiScale = CalculateDPIScale();
if (newDpiScale != dpiScale_) {
dpiScale_ = newDpiScale;
ClearCache();
ClearFonts();
}
// Drop old strings. Use a prime number to reduce clashing with other rhythms
if (frameCount_ % 23 == 0) {
for (auto iter = cache_.begin(); iter != cache_.end();) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
if (iter->second->texture)
iter->second->texture->Release();
cache_.erase(iter++);
} else {
iter++;
}
}
for (auto iter = sizeCache_.begin(); iter != sizeCache_.end(); ) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
sizeCache_.erase(iter++);
} else {
iter++;
}
}
}
}
#endif

View File

@ -18,14 +18,11 @@ public:
void SetFont(uint32_t fontHandle) override; // Shortcut once you've set the font once.
void MeasureString(std::string_view str, float *w, float *h) override;
bool DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) override;
// Use for housekeeping like throwing out old strings.
void OncePerFrame() override;
protected:
bool SupportsColorEmoji() const override { return false; }
void ClearFonts() override;
void ClearCache() override;
std::map<uint32_t, QFont *> fontMap_;
};

View File

@ -405,46 +405,4 @@ void TextDrawerSDL::ClearFonts() {
fallbackFonts_.clear();
}
void TextDrawerSDL::OncePerFrame() {
// Reset everything if DPI changes
float newDpiScale = CalculateDPIScale();
if (newDpiScale != dpiScale_) {
dpiScale_ = newDpiScale;
ClearCache();
ClearFonts();
}
// Drop old strings. Use a prime number to reduce clashing with other rhythms
if (frameCount_ % 23 == 0) {
for (auto iter = cache_.begin(); iter != cache_.end();) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
if (iter->second->texture)
iter->second->texture->Release();
cache_.erase(iter++);
} else {
iter++;
}
}
for (auto iter = sizeCache_.begin(); iter != sizeCache_.end(); ) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
sizeCache_.erase(iter++);
} else {
iter++;
}
}
}
}
void TextDrawerSDL::ClearCache() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
fontHash_ = 0;
}
#endif

View File

@ -21,13 +21,9 @@ public:
void SetFont(uint32_t fontHandle) override; // Shortcut once you've set the font once.
void MeasureString(std::string_view str, float *w, float *h) override;
bool DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) override;
// Use for housekeeping like throwing out old strings.
void OncePerFrame() override;
protected:
bool SupportsColorEmoji() const override { return false; }
void ClearCache() override;
void ClearFonts() override;
private:

View File

@ -384,45 +384,4 @@ void TextDrawerUWP::ClearFonts() {
fontMap_.clear();
}
void TextDrawerUWP::ClearCache() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
}
void TextDrawerUWP::OncePerFrame() {
frameCount_++;
// If DPI changed (small-mode, future proper monitor DPI support), drop everything.
float newDpiScale = CalculateDPIScale();
if (newDpiScale != dpiScale_) {
dpiScale_ = newDpiScale;
ClearCache();
ClearFonts();
}
// Drop old strings. Use a prime number to reduce clashing with other rhythms
if (frameCount_ % 23 == 0) {
for (auto iter = cache_.begin(); iter != cache_.end();) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
if (iter->second->texture)
iter->second->texture->Release();
cache_.erase(iter++);
} else {
iter++;
}
}
for (auto iter = sizeCache_.begin(); iter != sizeCache_.end(); ) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
sizeCache_.erase(iter++);
} else {
iter++;
}
}
}
}
#endif

View File

@ -23,13 +23,9 @@ public:
void SetFont(uint32_t fontHandle) override; // Shortcut once you've set the font once.
void MeasureString(std::string_view str, float *w, float *h) override;
bool DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) override;
// Use for housekeeping like throwing out old strings.
void OncePerFrame() override;
protected:
bool SupportsColorEmoji() const override { return true; }
void ClearCache() override;
void ClearFonts() override;
TextDrawerContext *ctx_;

View File

@ -261,45 +261,4 @@ void TextDrawerWin32::ClearFonts() {
fontMap_.clear();
}
void TextDrawerWin32::ClearCache() {
for (auto &iter : cache_) {
if (iter.second->texture)
iter.second->texture->Release();
}
cache_.clear();
sizeCache_.clear();
}
void TextDrawerWin32::OncePerFrame() {
frameCount_++;
// If DPI changed (small-mode, future proper monitor DPI support), drop everything.
float newDpiScale = CalculateDPIScale();
if (newDpiScale != dpiScale_) {
dpiScale_ = newDpiScale;
ClearCache();
ClearFonts();
}
// Drop old strings. Use a prime number to reduce clashing with other rhythms
if (frameCount_ % 23 == 0) {
for (auto iter = cache_.begin(); iter != cache_.end();) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
if (iter->second->texture)
iter->second->texture->Release();
cache_.erase(iter++);
} else {
iter++;
}
}
for (auto iter = sizeCache_.begin(); iter != sizeCache_.end(); ) {
if (frameCount_ - iter->second->lastUsedFrame > 100) {
sizeCache_.erase(iter++);
} else {
iter++;
}
}
}
}
#endif

View File

@ -23,13 +23,9 @@ public:
void SetFont(uint32_t fontHandle) override; // Shortcut once you've set the font once.
void MeasureString(std::string_view str, float *w, float *h) override;
bool DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStringEntry &entry, Draw::DataFormat texFormat, std::string_view str, int align, bool fullColor) override;
// Use for housekeeping like throwing out old strings.
void OncePerFrame() override;
protected:
bool SupportsColorEmoji() const override { return false; }
void ClearCache() override;
void ClearFonts() override;
TextDrawerContext *ctx_;