From d6ed79f02ad388e61fb24f33df3d9c47ea6e2437 Mon Sep 17 00:00:00 2001 From: Alex <48759429+Aurumaker72@users.noreply.github.com> Date: Fri, 30 Jun 2023 22:02:03 +0200 Subject: [PATCH] Lua D2D API cache IDWriteTextLayout --- lua/LuaConsole.cpp | 65 ++++++++++++++++++++++++++++++++-------------- lua/LuaConsole.h | 47 +++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 20 deletions(-) diff --git a/lua/LuaConsole.cpp b/lua/LuaConsole.cpp index 84462f03..6a2e7563 100644 --- a/lua/LuaConsole.cpp +++ b/lua/LuaConsole.cpp @@ -130,6 +130,7 @@ namespace LuaEngine { IDWriteFactory* dw_factory; std::unordered_map d2d_brush_cache; std::unordered_map d2d_bitmap_cache; + std::unordered_map, IDWriteTextLayout*> dw_text_layout_cache; //improved debug print from stackoverflow, now shows function info #ifdef _DEBUG static void stackDump(lua_State* L) { @@ -592,16 +593,22 @@ namespace LuaEngine { d2d_factory->Release(); d2d_render_target->Release(); - for (auto const& [key, val] : d2d_brush_cache) { + for (auto const& [_, val] : d2d_brush_cache) { val->Release(); } d2d_brush_cache.clear(); - for (auto const& [key, val] : d2d_bitmap_cache) { + for (auto const& [_, val] : d2d_bitmap_cache) { val->Release(); } d2d_bitmap_cache.clear(); + for (auto const& [_, val] : dw_text_layout_cache) { + val->Release(); + } + dw_text_layout_cache.clear(); + + ReleaseDC(mainHWND, lua_dc); lua_dc = NULL; d2d_factory = NULL; @@ -1883,34 +1890,52 @@ namespace LuaEngine { int horizontal_alignment = luaL_checkinteger(L, 14); int vertical_alignment = luaL_checkinteger(L, 15); int options = luaL_checkinteger(L, 16); - - IDWriteTextFormat* text_format; - dw_factory->CreateTextFormat( - widen(font_name).c_str(), - NULL, - (DWRITE_FONT_WEIGHT)font_weight, - (DWRITE_FONT_STYLE)font_style, - DWRITE_FONT_STRETCH_NORMAL, + auto tuple = std::make_tuple( + text, + font_weight, + font_style, font_size, - L"", - &text_format + rectangle.left, + rectangle.top, + rectangle.right, + rectangle.bottom, + horizontal_alignment, + vertical_alignment, + options ); - text_format->SetTextAlignment((DWRITE_TEXT_ALIGNMENT)horizontal_alignment); - text_format->SetParagraphAlignment((DWRITE_PARAGRAPH_ALIGNMENT)vertical_alignment); + if (!dw_text_layout_cache.contains(tuple)) { + IDWriteTextFormat* text_format; + + dw_factory->CreateTextFormat( + widen(font_name).c_str(), + NULL, + (DWRITE_FONT_WEIGHT)font_weight, + (DWRITE_FONT_STYLE)font_style, + DWRITE_FONT_STRETCH_NORMAL, + font_size, + L"", + &text_format + ); - IDWriteTextLayout* text_layout; + text_format->SetTextAlignment((DWRITE_TEXT_ALIGNMENT)horizontal_alignment); + text_format->SetParagraphAlignment((DWRITE_PARAGRAPH_ALIGNMENT)vertical_alignment); - dw_factory->CreateTextLayout(text.c_str(), text.length(), text_format, rectangle.right - rectangle.left, rectangle.bottom - rectangle.top, &text_layout); + IDWriteTextLayout* text_layout; + + dw_factory->CreateTextLayout(text.c_str(), text.length(), text_format, rectangle.right - rectangle.left, rectangle.bottom - rectangle.top, &text_layout); + + text_format->Release(); + + dw_text_layout_cache[tuple] = text_layout; + } + d2d_render_target->DrawTextLayout({ .x = rectangle.left, .y = rectangle.top, - }, text_layout, brush, (D2D1_DRAW_TEXT_OPTIONS)options); - - text_format->Release(); - text_layout->Release(); + }, dw_text_layout_cache[tuple], brush, (D2D1_DRAW_TEXT_OPTIONS)options); return 0; } diff --git a/lua/LuaConsole.h b/lua/LuaConsole.h index 8cc041ce..1f3f5f3d 100755 --- a/lua/LuaConsole.h +++ b/lua/LuaConsole.h @@ -76,6 +76,53 @@ inline static std::wstring widen(const std::string& str) { return ws; } +// goddamn core polluting with macros +#undef Index +// https://stackoverflow.com/a/7115547/14472122 +#include +namespace std { + namespace { + + // Code from boost + // Reciprocal of the golden ratio helps spread entropy + // and handles duplicates. + // See Mike Seymour in magic-numbers-in-boosthash-combine: + // http://stackoverflow.com/questions/4948780 + + template + inline void hash_combine(std::size_t& seed, T const& v) { + seed ^= std::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + } + + // Recursive template code derived from Matthieu M. + template ::value - 1> + struct HashValueImpl { + static void apply(size_t& seed, Tuple const& tuple) { + HashValueImpl::apply(seed, tuple); + hash_combine(seed, std::get(tuple)); + } + }; + + template + struct HashValueImpl { + static void apply(size_t& seed, Tuple const& tuple) { + hash_combine(seed, std::get<0>(tuple)); + } + }; + } + + template + struct hash> { + size_t + operator()(std::tuple const& tt) const { + size_t seed = 0; + HashValueImpl >::apply(seed, tt); + return seed; + } + + }; +} + #endif