From cfa9fe568d0684eb8f3b22fbf2641302c6a5aa27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20B=C3=A1lint=20Misius?= Date: Sat, 9 Dec 2023 09:51:41 +0100 Subject: [PATCH] Move graphics cache to SimulationData --- src/graphics/Renderer.cpp | 26 +++++++++++++++----------- src/graphics/Renderer.h | 25 +------------------------ src/graphics/RendererBasic.cpp | 9 --------- src/graphics/gcache_item.h | 15 +++++++++++++++ src/gui/game/GameView.cpp | 3 +++ src/gui/render/RenderView.cpp | 4 ++++ src/lua/LegacyLuaAPI.cpp | 2 +- src/lua/LuaScriptInterface.cpp | 19 +++++++------------ src/simulation/SaveRenderer.cpp | 6 ------ src/simulation/SaveRenderer.h | 1 - src/simulation/SimulationData.h | 2 ++ src/simulation/elements/PIPE.cpp | 21 +++++++++++---------- 12 files changed, 59 insertions(+), 74 deletions(-) create mode 100644 src/graphics/gcache_item.h diff --git a/src/graphics/Renderer.cpp b/src/graphics/Renderer.cpp index 9179d52cc..569d8df26 100644 --- a/src/graphics/Renderer.cpp +++ b/src/graphics/Renderer.cpp @@ -173,6 +173,7 @@ void Renderer::render_parts() { auto &sd = SimulationData::CRef(); auto &elements = sd.elements; + auto &graphicscache = sd.graphicscache; int deca, decr, decg, decb, cola, colr, colg, colb, firea, firer, fireg, fireb, pixel_mode, q, i, t, nx, ny, x, y; int orbd[4] = {0, 0, 0, 0}, orbl[4] = {0, 0, 0, 0}; Particle * parts; @@ -244,18 +245,21 @@ void Renderer::render_parts() else if(!(colour_mode & COLOUR_BASC)) { auto *graphics = useGraphicsFunction ? elements[t].Graphics : nullptr; - if (!graphics || graphics(this, &(sim->parts[i]), nx, ny, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb)) //That's a lot of args, a struct might be better + auto makeReady = !graphics || graphics(this, &(sim->parts[i]), nx, ny, &pixel_mode, &cola, &colr, &colg, &colb, &firea, &firer, &fireg, &fireb); //That's a lot of args, a struct might be better + if (makeReady && useGraphicsFunction) { - graphicscache[t].isready = 1; - graphicscache[t].pixel_mode = pixel_mode; - graphicscache[t].cola = cola; - graphicscache[t].colr = colr; - graphicscache[t].colg = colg; - graphicscache[t].colb = colb; - graphicscache[t].firea = firea; - graphicscache[t].firer = firer; - graphicscache[t].fireg = fireg; - graphicscache[t].fireb = fireb; + // I sure hope we locked sd.elementGraphicsMx exclusively + auto &wgraphicscache = SimulationData::Ref().graphicscache; + wgraphicscache[t].isready = 1; + wgraphicscache[t].pixel_mode = pixel_mode; + wgraphicscache[t].cola = cola; + wgraphicscache[t].colr = colr; + wgraphicscache[t].colg = colg; + wgraphicscache[t].colb = colb; + wgraphicscache[t].firea = firea; + wgraphicscache[t].firer = firer; + wgraphicscache[t].fireg = fireg; + wgraphicscache[t].fireb = fireb; } } if((elements[t].Properties & PROP_HOT_GLOW) && sim->parts[i].temp>(elements[t].HighTemperature-800.0f)) diff --git a/src/graphics/Renderer.h b/src/graphics/Renderer.h index d1f2b0909..98efee53a 100644 --- a/src/graphics/Renderer.h +++ b/src/graphics/Renderer.h @@ -1,5 +1,6 @@ #pragma once #include "Graphics.h" +#include "gui/game/RenderPreset.h" #include "gui/interface/Point.h" #include "common/tpt-rand.h" #include "SimulationConfig.h" @@ -13,28 +14,6 @@ class RenderPreset; class Simulation; -struct gcache_item -{ - int isready; - int pixel_mode; - int cola, colr, colg, colb; - int firea, firer, fireg, fireb; - gcache_item() : - isready(0), - pixel_mode(0), - cola(0), - colr(0), - colg(0), - colb(0), - firea(0), - firer(0), - fireg(0), - fireb(0) - { - } -}; -typedef struct gcache_item gcache_item; - int HeatToColour(float temp); class Renderer: public RasterDrawMethods @@ -65,7 +44,6 @@ public: RNG rng; Simulation * sim; - gcache_item *graphicscache; std::vector render_modes; unsigned int render_mode; @@ -148,7 +126,6 @@ public: static std::unique_ptr WallIcon(int wallID, Vec2 size); Renderer(Simulation * sim); - ~Renderer(); #define RENDERER_TABLE(name) \ static std::vector> name; \ diff --git a/src/graphics/RendererBasic.cpp b/src/graphics/RendererBasic.cpp index 1d4efbf08..43f892732 100644 --- a/src/graphics/RendererBasic.cpp +++ b/src/graphics/RendererBasic.cpp @@ -323,10 +323,6 @@ Renderer::Renderer(Simulation * sim): COLOUR_LIFE }); - //Prepare the graphics cache - graphicscache = new gcache_item[PT_NUM]; - std::fill(&graphicscache[0], &graphicscache[0] + PT_NUM, gcache_item()); - prepare_alpha(CELL, 1.0f); } @@ -466,9 +462,4 @@ VideoBuffer Renderer::DumpFrame() return newBuffer; } -Renderer::~Renderer() -{ - delete[] graphicscache; -} - template struct RasterDrawMethods; diff --git a/src/graphics/gcache_item.h b/src/graphics/gcache_item.h new file mode 100644 index 000000000..b824ae359 --- /dev/null +++ b/src/graphics/gcache_item.h @@ -0,0 +1,15 @@ +#pragma once + +struct gcache_item +{ + int isready = 0; + int pixel_mode = 0; + int cola = 0; + int colr = 0; + int colg = 0; + int colb = 0; + int firea = 0; + int firer = 0; + int fireg = 0; + int fireb = 0; +}; diff --git a/src/gui/game/GameView.cpp b/src/gui/game/GameView.cpp index 19d9c2781..9599efc92 100644 --- a/src/gui/game/GameView.cpp +++ b/src/gui/game/GameView.cpp @@ -2108,6 +2108,9 @@ void GameView::OnDraw() Graphics * g = GetGraphics(); if (ren) { + // we're the main thread, we may write graphicscache + auto &sd = SimulationData::Ref(); + std::unique_lock lk(sd.elementGraphicsMx); ren->clearScreen(); ren->RenderBegin(); ren->SetSample(c->PointTranslate(currentMouse)); diff --git a/src/gui/render/RenderView.cpp b/src/gui/render/RenderView.cpp index d64286407..2fbb19e3f 100644 --- a/src/gui/render/RenderView.cpp +++ b/src/gui/render/RenderView.cpp @@ -1,6 +1,7 @@ #include "RenderView.h" #include "simulation/ElementGraphics.h" +#include "simulation/SimulationData.h" #include "graphics/Graphics.h" #include "graphics/Renderer.h" @@ -158,6 +159,9 @@ void RenderView::OnDraw() g->DrawFilledRect(WINDOW.OriginRect(), 0x000000_rgb); if(ren) { + // we're the main thread, we may write graphicscache + auto &sd = SimulationData::Ref(); + std::unique_lock lk(sd.elementGraphicsMx); ren->clearScreen(); ren->RenderBegin(); ren->RenderEnd(); diff --git a/src/lua/LegacyLuaAPI.cpp b/src/lua/LegacyLuaAPI.cpp index 06ade0ef2..6eae5d11a 100644 --- a/src/lua/LegacyLuaAPI.cpp +++ b/src/lua/LegacyLuaAPI.cpp @@ -263,7 +263,7 @@ int luacon_elementwrite(lua_State* l) luacon_model->BuildMenus(); auto *luacon_ci = static_cast(commandInterface); luacon_ci->custom_init_can_move(); - std::fill(&luacon_ren->graphicscache[0], &luacon_ren->graphicscache[0] + PT_NUM, gcache_item()); + sd.graphicscache = std::array(); return 0; } diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp index d5625b6b7..b3e24c9bf 100644 --- a/src/lua/LuaScriptInterface.cpp +++ b/src/lua/LuaScriptInterface.cpp @@ -3286,6 +3286,7 @@ void LuaScriptInterface::LuaSetParticleProperty(lua_State* l, int particleID, St int LuaScriptInterface::elements_loadDefault(lua_State * l) { + auto &sd = SimulationData::Ref(); auto &builtinElements = GetElements(); auto *luacon_ci = static_cast(commandInterface); { @@ -3304,7 +3305,6 @@ int LuaScriptInterface::elements_loadDefault(lua_State * l) lua_settable(l, -3); { - auto &sd = SimulationData::Ref(); std::unique_lock lk(sd.elementGraphicsMx); auto &elements = sd.elements; if (id < (int)builtinElements.size()) @@ -3321,7 +3321,6 @@ int LuaScriptInterface::elements_loadDefault(lua_State * l) else { { - auto &sd = SimulationData::Ref(); std::unique_lock lk(sd.elementGraphicsMx); auto &elements = sd.elements; for (int i = 0; i < PT_NUM; i++) @@ -3355,8 +3354,7 @@ int LuaScriptInterface::elements_loadDefault(lua_State * l) } } luacon_ci->custom_init_can_move(); - std::fill(luacon_ren->graphicscache, luacon_ren->graphicscache+PT_NUM, gcache_item()); - SaveRenderer::Ref().Flush(0, PT_NUM); + sd.graphicscache = std::array(); return 0; } @@ -3639,8 +3637,8 @@ int LuaScriptInterface::elements_element(lua_State * l) if (lua_gettop(l) > 1) { + auto &sd = SimulationData::Ref(); { - auto &sd = SimulationData::Ref(); std::unique_lock lk(sd.elementGraphicsMx); auto &elements = sd.elements; luaL_checktype(l, 2, LUA_TTABLE); @@ -3744,8 +3742,7 @@ int LuaScriptInterface::elements_element(lua_State * l) luacon_model->BuildMenus(); luacon_ci->custom_init_can_move(); - luacon_ren->graphicscache[id].isready = 0; - SaveRenderer::Ref().Flush(id, id + 1); + sd.graphicscache[id].isready = 0; return 0; } @@ -3846,6 +3843,7 @@ int LuaScriptInterface::elements_property(lua_State * l) { if (prop != properties.end()) { + auto &sd = SimulationData::Ref(); if (lua_type(l, 3) != LUA_TNIL) { if (prop->Type == StructProperty::TransitionType) @@ -3857,7 +3855,6 @@ int LuaScriptInterface::elements_property(lua_State * l) } } { - auto &sd = SimulationData::Ref(); std::unique_lock lk(sd.elementGraphicsMx); auto &elements = sd.elements; intptr_t propertyAddress = (intptr_t)(((unsigned char*)&elements[id]) + prop->Offset); @@ -3867,8 +3864,7 @@ int LuaScriptInterface::elements_property(lua_State * l) luacon_model->BuildMenus(); luacon_ci->custom_init_can_move(); - luacon_ren->graphicscache[id].isready = 0; - SaveRenderer::Ref().Flush(id, id + 1); + sd.graphicscache[id].isready = 0; } else if (propertyName == "Update") { @@ -3914,8 +3910,7 @@ int LuaScriptInterface::elements_property(lua_State * l) lua_gr_func[id].Clear(); elements[id].Graphics = builtinElements[id].Graphics; } - luacon_ren->graphicscache[id].isready = 0; - SaveRenderer::Ref().Flush(id, id + 1); + sd.graphicscache[id].isready = 0; } else if (propertyName == "Create") { diff --git a/src/simulation/SaveRenderer.cpp b/src/simulation/SaveRenderer.cpp index 63dea381d..65c6f73ee 100644 --- a/src/simulation/SaveRenderer.cpp +++ b/src/simulation/SaveRenderer.cpp @@ -15,12 +15,6 @@ SaveRenderer::SaveRenderer(){ ren->blackDecorations = true; } -void SaveRenderer::Flush(int begin, int end) -{ - std::lock_guard gx(renderMutex); - std::fill(ren->graphicscache + begin, ren->graphicscache + end, gcache_item()); -} - std::pair, MissingElements> SaveRenderer::Render(const GameSave *save, bool decorations, bool fire, Renderer *renderModeSource) { // this function usually runs on a thread different from where element info in SimulationData may be written, so we acquire a read-only lock on it diff --git a/src/simulation/SaveRenderer.h b/src/simulation/SaveRenderer.h index d2a245339..65a8ac4ab 100644 --- a/src/simulation/SaveRenderer.h +++ b/src/simulation/SaveRenderer.h @@ -20,6 +20,5 @@ class SaveRenderer: public ExplicitSingleton { public: SaveRenderer(); std::pair, MissingElements> Render(const GameSave *save, bool decorations = true, bool fire = true, Renderer *renderModeSource = nullptr); - void Flush(int begin, int end); virtual ~SaveRenderer(); }; diff --git a/src/simulation/SimulationData.h b/src/simulation/SimulationData.h index 6f7ae5421..0f8bebda3 100644 --- a/src/simulation/SimulationData.h +++ b/src/simulation/SimulationData.h @@ -9,6 +9,7 @@ #include "Element.h" #include "Particle.h" #include "WallType.h" +#include "graphics/gcache_item.h" #include #include #include @@ -173,6 +174,7 @@ class SimulationData : public ExplicitSingleton { public: std::array elements; + std::array graphicscache; std::vector tools; std::vector wtypes; std::vector msections; diff --git a/src/simulation/elements/PIPE.cpp b/src/simulation/elements/PIPE.cpp index 717d7b459..51df18f27 100644 --- a/src/simulation/elements/PIPE.cpp +++ b/src/simulation/elements/PIPE.cpp @@ -348,22 +348,23 @@ int Element_PIPE_graphics(GRAPHICS_FUNC_ARGS) { auto &sd = SimulationData::CRef(); auto &elements = sd.elements; + auto &graphicscache = sd.graphicscache; int t = TYP(cpart->ctype); if (t>0 && tgraphicscache[t].isready) + if (graphicscache[t].isready) { - *pixel_mode = ren->graphicscache[t].pixel_mode; - *cola = ren->graphicscache[t].cola; - *colr = ren->graphicscache[t].colr; - *colg = ren->graphicscache[t].colg; - *colb = ren->graphicscache[t].colb; - *firea = ren->graphicscache[t].firea; - *firer = ren->graphicscache[t].firer; - *fireg = ren->graphicscache[t].fireg; - *fireb = ren->graphicscache[t].fireb; + *pixel_mode = graphicscache[t].pixel_mode; + *cola = graphicscache[t].cola; + *colr = graphicscache[t].colr; + *colg = graphicscache[t].colg; + *colb = graphicscache[t].colb; + *firea = graphicscache[t].firea; + *firer = graphicscache[t].firer; + *fireg = graphicscache[t].fireg; + *fireb = graphicscache[t].fireb; } else {